Add additional coverage for ESPHome sensor and number (#95226)

This commit is contained in:
J. Nick Koston 2023-06-26 05:29:38 -05:00 committed by GitHub
parent 74fb1ba51d
commit ad17a89531
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 188 additions and 5 deletions

View File

@ -312,7 +312,6 @@ omit =
homeassistant/components/esphome/domain_data.py
homeassistant/components/esphome/entry_data.py
homeassistant/components/esphome/light.py
homeassistant/components/esphome/number.py
homeassistant/components/esphome/switch.py
homeassistant/components/etherscan/sensor.py
homeassistant/components/eufy/*

View File

@ -74,9 +74,7 @@ class EsphomeNumber(EsphomeEntity[NumberInfo, NumberState], NumberEntity):
def native_value(self) -> float | None:
"""Return the state of the entity."""
state = self._state
if math.isnan(state.state):
return None
if state.missing_state:
if state.missing_state or math.isnan(state.state):
return None
return state.state

View File

@ -0,0 +1,91 @@
"""Test ESPHome numbers."""
import math
from unittest.mock import call
from aioesphomeapi import (
APIClient,
NumberInfo,
NumberMode as ESPHomeNumberMode,
NumberState,
)
from homeassistant.components.number import (
ATTR_VALUE,
DOMAIN as NUMBER_DOMAIN,
SERVICE_SET_VALUE,
)
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN
from homeassistant.core import HomeAssistant
async def test_generic_number_entity(
hass: HomeAssistant,
mock_client: APIClient,
mock_generic_device_entry,
) -> None:
"""Test a generic number entity."""
entity_info = [
NumberInfo(
object_id="mynumber",
key=1,
name="my number",
unique_id="my_number",
max_value=100,
min_value=0,
step=1,
unit_of_measurement="%",
)
]
states = [NumberState(key=1, state=50)]
user_service = []
await mock_generic_device_entry(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("number.test_my_number")
assert state is not None
assert state.state == "50"
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: "number.test_my_number", ATTR_VALUE: 50},
blocking=True,
)
mock_client.number_command.assert_has_calls([call(1, 50)])
mock_client.number_command.reset_mock()
async def test_generic_number_nan(
hass: HomeAssistant,
mock_client: APIClient,
mock_generic_device_entry,
) -> None:
"""Test a generic number entity with nan state."""
entity_info = [
NumberInfo(
object_id="mynumber",
key=1,
name="my number",
unique_id="my_number",
max_value=100,
min_value=0,
step=1,
unit_of_measurement="%",
mode=ESPHomeNumberMode.SLIDER,
)
]
states = [NumberState(key=1, state=math.nan)]
user_service = []
await mock_generic_device_entry(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("number.test_my_number")
assert state is not None
assert state.state == STATE_UNKNOWN

View File

@ -1,6 +1,9 @@
"""Test ESPHome sensors."""
import math
from aioesphomeapi import (
APIClient,
EntityCategory as ESPHomeEntityCategory,
LastResetType,
SensorInfo,
SensorState,
@ -10,8 +13,10 @@ from aioesphomeapi import (
)
from homeassistant.components.sensor import ATTR_STATE_CLASS, SensorStateClass
from homeassistant.const import STATE_UNKNOWN
from homeassistant.const import ATTR_ICON, STATE_UNKNOWN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity import EntityCategory
async def test_generic_numeric_sensor(
@ -41,6 +46,41 @@ async def test_generic_numeric_sensor(
assert state.state == "50"
async def test_generic_numeric_sensor_with_entity_category_and_icon(
hass: HomeAssistant,
mock_client: APIClient,
mock_generic_device_entry,
) -> None:
"""Test a generic sensor entity."""
entity_info = [
SensorInfo(
object_id="mysensor",
key=1,
name="my sensor",
unique_id="my_sensor",
entity_category=ESPHomeEntityCategory.CONFIG,
icon="mdi:leaf",
)
]
states = [SensorState(key=1, state=50)]
user_service = []
await mock_generic_device_entry(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("sensor.test_my_sensor")
assert state is not None
assert state.state == "50"
assert state.attributes[ATTR_ICON] == "mdi:leaf"
entity_reg = er.async_get(hass)
entry = entity_reg.async_get("sensor.test_my_sensor")
assert entry is not None
assert entry.unique_id == "my_sensor"
assert entry.entity_category is EntityCategory.CONFIG
async def test_generic_numeric_sensor_state_class_measurement(
hass: HomeAssistant,
mock_client: APIClient,
@ -70,6 +110,11 @@ async def test_generic_numeric_sensor_state_class_measurement(
assert state is not None
assert state.state == "50"
assert state.attributes[ATTR_STATE_CLASS] == SensorStateClass.MEASUREMENT
entity_reg = er.async_get(hass)
entry = entity_reg.async_get("sensor.test_my_sensor")
assert entry is not None
assert entry.unique_id == "my_sensor"
assert entry.entity_category is None
async def test_generic_numeric_sensor_device_class_timestamp(
@ -130,6 +175,56 @@ async def test_generic_numeric_sensor_legacy_last_reset_convert(
assert state.attributes[ATTR_STATE_CLASS] == SensorStateClass.TOTAL_INCREASING
async def test_generic_numeric_sensor_no_state(
hass: HomeAssistant, mock_client: APIClient, mock_generic_device_entry
) -> None:
"""Test a generic numeric sensor that has no state."""
entity_info = [
SensorInfo(
object_id="mysensor",
key=1,
name="my sensor",
unique_id="my_sensor",
)
]
states = []
user_service = []
await mock_generic_device_entry(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("sensor.test_my_sensor")
assert state is not None
assert state.state == STATE_UNKNOWN
async def test_generic_numeric_sensor_nan_state(
hass: HomeAssistant, mock_client: APIClient, mock_generic_device_entry
) -> None:
"""Test a generic numeric sensor that has nan state."""
entity_info = [
SensorInfo(
object_id="mysensor",
key=1,
name="my sensor",
unique_id="my_sensor",
)
]
states = [SensorState(key=1, state=math.nan, missing_state=False)]
user_service = []
await mock_generic_device_entry(
mock_client=mock_client,
entity_info=entity_info,
user_service=user_service,
states=states,
)
state = hass.states.get("sensor.test_my_sensor")
assert state is not None
assert state.state == STATE_UNKNOWN
async def test_generic_numeric_sensor_missing_state(
hass: HomeAssistant, mock_client: APIClient, mock_generic_device_entry
) -> None: