core/tests/components/miele/test_sensor.py

274 lines
11 KiB
Python

"""Tests for miele sensor module."""
from datetime import timedelta
from unittest.mock import MagicMock
from freezegun.api import FrozenDateTimeFactory
from pymiele import MieleDevices
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.miele.const import DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from tests.common import (
MockConfigEntry,
async_fire_time_changed,
async_load_json_object_fixture,
snapshot_platform,
)
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_states(
hass: HomeAssistant,
mock_miele_client: MagicMock,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
setup_platform: MockConfigEntry,
) -> None:
"""Test sensor state after polling the API for data."""
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_states_api_push(
hass: HomeAssistant,
mock_miele_client: MagicMock,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
setup_platform: MockConfigEntry,
push_data_and_actions: None,
) -> None:
"""Test sensor state when the API pushes data via SSE."""
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)
@pytest.mark.parametrize("load_device_file", ["hob.json"])
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_hob_sensor_states(
hass: HomeAssistant,
mock_miele_client: MagicMock,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
setup_platform: None,
) -> None:
"""Test sensor state."""
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)
@pytest.mark.parametrize("load_device_file", ["fridge_freezer.json"])
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_fridge_freezer_sensor_states(
hass: HomeAssistant,
mock_miele_client: MagicMock,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
setup_platform: None,
) -> None:
"""Test sensor state."""
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)
@pytest.mark.parametrize("load_device_file", ["oven.json"])
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
async def test_oven_temperatures_scenario(
hass: HomeAssistant,
mock_miele_client: MagicMock,
setup_platform: None,
mock_config_entry: MockConfigEntry,
device_fixture: MieleDevices,
freezer: FrozenDateTimeFactory,
) -> None:
"""Parametrized test for verifying temperature sensors for oven devices."""
# Initial state when the oven is and created for the first time - don't know if it supports core temperature (probe)
check_sensor_state(hass, "sensor.oven_temperature", "unknown", 0)
check_sensor_state(hass, "sensor.oven_target_temperature", "unknown", 0)
check_sensor_state(hass, "sensor.oven_core_temperature", None, 0)
check_sensor_state(hass, "sensor.oven_core_target_temperature", None, 0)
# Simulate temperature settings, no probe temperature
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_raw"] = 8000
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_localized"] = (
80.0
)
device_fixture["DummyOven"]["state"]["temperature"][0]["value_raw"] = 2150
device_fixture["DummyOven"]["state"]["temperature"][0]["value_localized"] = 21.5
freezer.tick(timedelta(seconds=130))
async_fire_time_changed(hass)
await hass.async_block_till_done()
check_sensor_state(hass, "sensor.oven_temperature", "21.5", 1)
check_sensor_state(hass, "sensor.oven_target_temperature", "80.0", 1)
check_sensor_state(hass, "sensor.oven_core_temperature", None, 1)
check_sensor_state(hass, "sensor.oven_core_target_temperature", None, 1)
# Simulate unsetting temperature
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_raw"] = -32768
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_localized"] = (
None
)
device_fixture["DummyOven"]["state"]["temperature"][0]["value_raw"] = -32768
device_fixture["DummyOven"]["state"]["temperature"][0]["value_localized"] = None
freezer.tick(timedelta(seconds=130))
async_fire_time_changed(hass)
await hass.async_block_till_done()
check_sensor_state(hass, "sensor.oven_temperature", "unknown", 2)
check_sensor_state(hass, "sensor.oven_target_temperature", "unknown", 2)
check_sensor_state(hass, "sensor.oven_core_temperature", None, 2)
check_sensor_state(hass, "sensor.oven_core_target_temperature", None, 2)
# Simulate temperature settings with probe temperature
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_raw"] = 8000
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_localized"] = (
80.0
)
device_fixture["DummyOven"]["state"]["coreTargetTemperature"][0]["value_raw"] = 3000
device_fixture["DummyOven"]["state"]["coreTargetTemperature"][0][
"value_localized"
] = 30.0
device_fixture["DummyOven"]["state"]["temperature"][0]["value_raw"] = 2183
device_fixture["DummyOven"]["state"]["temperature"][0]["value_localized"] = 21.83
device_fixture["DummyOven"]["state"]["coreTemperature"][0]["value_raw"] = 2200
device_fixture["DummyOven"]["state"]["coreTemperature"][0]["value_localized"] = 22.0
freezer.tick(timedelta(seconds=130))
async_fire_time_changed(hass)
await hass.async_block_till_done()
check_sensor_state(hass, "sensor.oven_temperature", "21.83", 3)
check_sensor_state(hass, "sensor.oven_target_temperature", "80.0", 3)
check_sensor_state(hass, "sensor.oven_core_temperature", "22.0", 2)
check_sensor_state(hass, "sensor.oven_core_target_temperature", "30.0", 3)
# Simulate unsetting temperature
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_raw"] = -32768
device_fixture["DummyOven"]["state"]["targetTemperature"][0]["value_localized"] = (
None
)
device_fixture["DummyOven"]["state"]["coreTargetTemperature"][0][
"value_raw"
] = -32768
device_fixture["DummyOven"]["state"]["coreTargetTemperature"][0][
"value_localized"
] = None
device_fixture["DummyOven"]["state"]["temperature"][0]["value_raw"] = -32768
device_fixture["DummyOven"]["state"]["temperature"][0]["value_localized"] = None
device_fixture["DummyOven"]["state"]["coreTemperature"][0]["value_raw"] = -32768
device_fixture["DummyOven"]["state"]["coreTemperature"][0]["value_localized"] = None
freezer.tick(timedelta(seconds=130))
async_fire_time_changed(hass)
await hass.async_block_till_done()
check_sensor_state(hass, "sensor.oven_temperature", "unknown", 4)
check_sensor_state(hass, "sensor.oven_target_temperature", "unknown", 4)
check_sensor_state(hass, "sensor.oven_core_temperature", "unknown", 4)
check_sensor_state(hass, "sensor.oven_core_target_temperature", "unknown", 4)
def check_sensor_state(
hass: HomeAssistant,
sensor_entity: str,
expected: str,
step: int,
):
"""Check the state of sensor matches the expected state."""
state = hass.states.get(sensor_entity)
if expected is None:
assert state is None, (
f"[{sensor_entity}] Step {step + 1}: got {state.state}, expected nothing"
)
else:
assert state is not None, f"Missing entity: {sensor_entity}"
assert state.state == expected, (
f"[{sensor_entity}] Step {step + 1}: got {state.state}, expected {expected}"
)
@pytest.mark.parametrize("load_device_file", ["oven.json"])
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
async def test_temperature_sensor_registry_lookup(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_miele_client: MagicMock,
setup_platform: None,
device_fixture: MieleDevices,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test that core temperature sensor is provided by the integration after looking up in entity registry."""
# Initial state, the oven is showing core temperature (probe)
freezer.tick(timedelta(seconds=130))
device_fixture["DummyOven"]["state"]["coreTemperature"][0]["value_raw"] = 2200
device_fixture["DummyOven"]["state"]["coreTemperature"][0]["value_localized"] = 22.0
async_fire_time_changed(hass)
await hass.async_block_till_done()
entity_id = "sensor.oven_core_temperature"
assert hass.states.get(entity_id) is not None
assert hass.states.get(entity_id).state == "22.0"
# reload device when turned off, reporting the invalid value
mock_miele_client.get_devices.return_value = await async_load_json_object_fixture(
hass, "oven.json", DOMAIN
)
# unload config entry and reload to make sure that the entity is still provided
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == "unavailable"
await hass.config_entries.async_reload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == "unknown"
@pytest.mark.parametrize("load_device_file", ["vacuum_device.json"])
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_vacuum_sensor_states(
hass: HomeAssistant,
mock_miele_client: MagicMock,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
setup_platform: None,
) -> None:
"""Test robot vacuum cleaner sensor state."""
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)
@pytest.mark.parametrize("load_device_file", ["fan_devices.json"])
@pytest.mark.parametrize("platforms", [(SENSOR_DOMAIN,)])
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_fan_hob_sensor_states(
hass: HomeAssistant,
mock_miele_client: MagicMock,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
setup_platform: None,
) -> None:
"""Test robot fan / hob sensor state."""
await snapshot_platform(hass, entity_registry, snapshot, setup_platform.entry_id)