mirror of https://github.com/home-assistant/core
291 lines
9.2 KiB
Python
291 lines
9.2 KiB
Python
"""Test for Nest sensors platform for the Smart Device Management API.
|
|
|
|
These tests fake out the subscriber/devicemanager, and are not using a real
|
|
pubsub subscriber.
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from google_nest_sdm.event import EventMessage
|
|
import pytest
|
|
|
|
from homeassistant.components.sensor import (
|
|
ATTR_STATE_CLASS,
|
|
SensorDeviceClass,
|
|
SensorStateClass,
|
|
)
|
|
from homeassistant.const import (
|
|
ATTR_DEVICE_CLASS,
|
|
ATTR_FRIENDLY_NAME,
|
|
ATTR_UNIT_OF_MEASUREMENT,
|
|
PERCENTAGE,
|
|
STATE_UNAVAILABLE,
|
|
UnitOfTemperature,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
|
|
|
from .common import DEVICE_ID, CreateDevice, FakeSubscriber, PlatformSetup
|
|
|
|
|
|
@pytest.fixture
|
|
def platforms() -> list[str]:
|
|
"""Fixture to setup the platforms to test."""
|
|
return ["sensor"]
|
|
|
|
|
|
@pytest.fixture
|
|
def device_traits() -> dict[str, Any]:
|
|
"""Fixture that sets default traits used for devices."""
|
|
return {"sdm.devices.traits.Info": {"customName": "My Sensor"}}
|
|
|
|
|
|
async def test_thermostat_device(
|
|
hass: HomeAssistant,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
create_device: CreateDevice,
|
|
setup_platform: PlatformSetup,
|
|
) -> None:
|
|
"""Test a thermostat with temperature and humidity sensors."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.1,
|
|
},
|
|
"sdm.devices.traits.Humidity": {
|
|
"ambientHumidityPercent": 35.0,
|
|
},
|
|
}
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == "25.1"
|
|
assert (
|
|
temperature.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
|
== UnitOfTemperature.CELSIUS
|
|
)
|
|
assert (
|
|
temperature.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.TEMPERATURE
|
|
)
|
|
assert temperature.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
|
assert temperature.attributes.get(ATTR_FRIENDLY_NAME) == "My Sensor Temperature"
|
|
|
|
humidity = hass.states.get("sensor.my_sensor_humidity")
|
|
assert humidity is not None
|
|
assert humidity.state == "35"
|
|
assert humidity.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
|
assert humidity.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.HUMIDITY
|
|
assert humidity.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
|
assert humidity.attributes.get(ATTR_FRIENDLY_NAME) == "My Sensor Humidity"
|
|
|
|
entry = entity_registry.async_get("sensor.my_sensor_temperature")
|
|
assert entry.unique_id == f"{DEVICE_ID}-temperature"
|
|
assert entry.domain == "sensor"
|
|
|
|
entry = entity_registry.async_get("sensor.my_sensor_humidity")
|
|
assert entry.unique_id == f"{DEVICE_ID}-humidity"
|
|
assert entry.domain == "sensor"
|
|
|
|
device = device_registry.async_get(entry.device_id)
|
|
assert device.name == "My Sensor"
|
|
assert device.model == "Thermostat"
|
|
assert device.identifiers == {("nest", DEVICE_ID)}
|
|
|
|
|
|
async def test_thermostat_device_available(
|
|
hass: HomeAssistant, create_device: CreateDevice, setup_platform: PlatformSetup
|
|
) -> None:
|
|
"""Test a thermostat with temperature and humidity sensors that is Online."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.1,
|
|
},
|
|
"sdm.devices.traits.Humidity": {
|
|
"ambientHumidityPercent": 35.0,
|
|
},
|
|
"sdm.devices.traits.Connectivity": {"status": "ONLINE"},
|
|
}
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == "25.1"
|
|
|
|
humidity = hass.states.get("sensor.my_sensor_humidity")
|
|
assert humidity is not None
|
|
assert humidity.state == "35"
|
|
|
|
|
|
async def test_thermostat_device_unavailable(
|
|
hass: HomeAssistant, create_device: CreateDevice, setup_platform: PlatformSetup
|
|
) -> None:
|
|
"""Test a thermostat with temperature and humidity sensors that is Offline."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.1,
|
|
},
|
|
"sdm.devices.traits.Humidity": {
|
|
"ambientHumidityPercent": 35.0,
|
|
},
|
|
"sdm.devices.traits.Connectivity": {"status": "OFFLINE"},
|
|
}
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == STATE_UNAVAILABLE
|
|
|
|
humidity = hass.states.get("sensor.my_sensor_humidity")
|
|
assert humidity is not None
|
|
assert humidity.state == STATE_UNAVAILABLE
|
|
|
|
|
|
async def test_no_devices(hass: HomeAssistant, setup_platform: PlatformSetup) -> None:
|
|
"""Test no devices returned by the api."""
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is None
|
|
|
|
humidity = hass.states.get("sensor.my_sensor_humidity")
|
|
assert humidity is None
|
|
|
|
|
|
async def test_device_no_sensor_traits(
|
|
hass: HomeAssistant, create_device: CreateDevice, setup_platform: PlatformSetup
|
|
) -> None:
|
|
"""Test a device with applicable sensor traits."""
|
|
create_device.create({})
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is None
|
|
|
|
humidity = hass.states.get("sensor.my_sensor_humidity")
|
|
assert humidity is None
|
|
|
|
|
|
@pytest.mark.parametrize("device_traits", [{}]) # Disable default name
|
|
async def test_device_name_from_structure(
|
|
hass: HomeAssistant, create_device: CreateDevice, setup_platform: PlatformSetup
|
|
) -> None:
|
|
"""Test a device without a custom name, inferring name from structure."""
|
|
create_device.create(
|
|
raw_traits={
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.2,
|
|
},
|
|
},
|
|
raw_data={
|
|
"parentRelations": [
|
|
{"parent": "some-structure-id", "displayName": "Some Room"}
|
|
],
|
|
},
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.some_room_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == "25.2"
|
|
|
|
|
|
async def test_event_updates_sensor(
|
|
hass: HomeAssistant,
|
|
subscriber: FakeSubscriber,
|
|
create_device: CreateDevice,
|
|
setup_platform: PlatformSetup,
|
|
) -> None:
|
|
"""Test a pubsub message received by subscriber to update temperature."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.1,
|
|
},
|
|
}
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == "25.1"
|
|
|
|
# Simulate a pubsub message received by the subscriber with a trait update
|
|
event = EventMessage.create_event(
|
|
{
|
|
"eventId": "some-event-id",
|
|
"timestamp": "2019-01-01T00:00:01Z",
|
|
"resourceUpdate": {
|
|
"name": DEVICE_ID,
|
|
"traits": {
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 26.2,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
auth=None,
|
|
)
|
|
await subscriber.async_receive_event(event)
|
|
await hass.async_block_till_done() # Process dispatch/update signal
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == "26.2"
|
|
|
|
|
|
@pytest.mark.parametrize("device_type", ["some-unknown-type"])
|
|
async def test_device_with_unknown_type(
|
|
hass: HomeAssistant,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
create_device: CreateDevice,
|
|
setup_platform: PlatformSetup,
|
|
) -> None:
|
|
"""Test a device without a custom name, inferring name from structure."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.1,
|
|
},
|
|
}
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature is not None
|
|
assert temperature.state == "25.1"
|
|
assert temperature.attributes.get(ATTR_FRIENDLY_NAME) == "My Sensor Temperature"
|
|
|
|
entry = entity_registry.async_get("sensor.my_sensor_temperature")
|
|
assert entry.unique_id == f"{DEVICE_ID}-temperature"
|
|
assert entry.domain == "sensor"
|
|
|
|
device = device_registry.async_get(entry.device_id)
|
|
assert device.name == "My Sensor"
|
|
assert device.model is None
|
|
assert device.identifiers == {("nest", DEVICE_ID)}
|
|
|
|
|
|
async def test_temperature_rounding(
|
|
hass: HomeAssistant, create_device: CreateDevice, setup_platform: PlatformSetup
|
|
) -> None:
|
|
"""Test the rounding of overly precise temperatures."""
|
|
create_device.create(
|
|
{
|
|
"sdm.devices.traits.Temperature": {
|
|
"ambientTemperatureCelsius": 25.15678,
|
|
},
|
|
}
|
|
)
|
|
await setup_platform()
|
|
|
|
temperature = hass.states.get("sensor.my_sensor_temperature")
|
|
assert temperature.state == "25.2"
|