Don't allow numerical sensor state to be NaN or inf (#98110)
parent
3b16a3e1e0
commit
e3b945a8d0
|
@ -8,7 +8,7 @@ from dataclasses import dataclass
|
|||
from datetime import UTC, date, datetime, timedelta
|
||||
from decimal import Decimal, InvalidOperation as DecimalInvalidOperation
|
||||
import logging
|
||||
from math import ceil, floor, log10
|
||||
from math import ceil, floor, isfinite, log10
|
||||
from typing import Any, Final, Self, cast, final
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -582,7 +582,11 @@ class SensorEntity(Entity):
|
|||
if not isinstance(value, (int, float, Decimal)):
|
||||
try:
|
||||
if isinstance(value, str) and "." not in value and "e" not in value:
|
||||
numerical_value = int(value)
|
||||
try:
|
||||
numerical_value = int(value)
|
||||
except ValueError:
|
||||
# Handle nan, inf
|
||||
numerical_value = float(value)
|
||||
else:
|
||||
numerical_value = float(value) # type:ignore[arg-type]
|
||||
except (TypeError, ValueError) as err:
|
||||
|
@ -596,6 +600,15 @@ class SensorEntity(Entity):
|
|||
else:
|
||||
numerical_value = value
|
||||
|
||||
if not isfinite(numerical_value):
|
||||
raise ValueError(
|
||||
f"Sensor {self.entity_id} has device class '{device_class}', "
|
||||
f"state class '{state_class}' unit '{unit_of_measurement}' and "
|
||||
f"suggested precision '{suggested_precision}' thus indicating it "
|
||||
f"has a numeric value; however, it has the non-finite value: "
|
||||
f"'{numerical_value}'"
|
||||
)
|
||||
|
||||
if native_unit_of_measurement != unit_of_measurement and (
|
||||
converter := UNIT_CONVERTERS.get(device_class)
|
||||
):
|
||||
|
|
|
@ -1861,13 +1861,17 @@ async def test_device_classes_with_invalid_unit_of_measurement(
|
|||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"native_value",
|
||||
("native_value", "problem"),
|
||||
[
|
||||
"",
|
||||
"abc",
|
||||
"13.7.1",
|
||||
datetime(2012, 11, 10, 7, 35, 1),
|
||||
date(2012, 11, 10),
|
||||
("", "non-numeric"),
|
||||
("abc", "non-numeric"),
|
||||
("13.7.1", "non-numeric"),
|
||||
(datetime(2012, 11, 10, 7, 35, 1), "non-numeric"),
|
||||
(date(2012, 11, 10), "non-numeric"),
|
||||
("inf", "non-finite"),
|
||||
(float("inf"), "non-finite"),
|
||||
("nan", "non-finite"),
|
||||
(float("nan"), "non-finite"),
|
||||
],
|
||||
)
|
||||
async def test_non_numeric_validation_error(
|
||||
|
@ -1875,6 +1879,7 @@ async def test_non_numeric_validation_error(
|
|||
caplog: pytest.LogCaptureFixture,
|
||||
enable_custom_integrations: None,
|
||||
native_value: Any,
|
||||
problem: str,
|
||||
device_class: SensorDeviceClass | None,
|
||||
state_class: SensorStateClass | None,
|
||||
unit: str | None,
|
||||
|
@ -1899,7 +1904,7 @@ async def test_non_numeric_validation_error(
|
|||
|
||||
assert (
|
||||
"thus indicating it has a numeric value; "
|
||||
f"however, it has the non-numeric value: '{native_value}'"
|
||||
f"however, it has the {problem} value: '{native_value}'"
|
||||
) in caplog.text
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue