core/tests/components/ring/test_sensor.py

208 lines
6.7 KiB
Python

"""The tests for the Ring sensor platform."""
import logging
from unittest.mock import patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from ring_doorbell import Ring
from homeassistant.components.ring.const import DOMAIN, SCAN_INTERVAL
from homeassistant.components.sensor import (
ATTR_STATE_CLASS,
DOMAIN as SENSOR_DOMAIN,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .common import setup_platform
from .device_mocks import FRONT_DEVICE_ID, FRONT_DOOR_DEVICE_ID, INGRESS_DEVICE_ID
from tests.common import async_fire_time_changed
async def test_sensor(hass: HomeAssistant, mock_ring_client) -> None:
"""Test the Ring sensors."""
await setup_platform(hass, "sensor")
front_battery_state = hass.states.get("sensor.front_battery")
assert front_battery_state is not None
assert front_battery_state.state == "80"
assert (
front_battery_state.attributes[ATTR_STATE_CLASS] == SensorStateClass.MEASUREMENT
)
front_door_battery_state = hass.states.get("sensor.front_door_battery")
assert front_door_battery_state is not None
assert front_door_battery_state.state == "100"
assert (
front_door_battery_state.attributes[ATTR_STATE_CLASS]
== SensorStateClass.MEASUREMENT
)
downstairs_volume_state = hass.states.get("sensor.downstairs_volume")
assert downstairs_volume_state is not None
assert downstairs_volume_state.state == "2"
ingress_mic_volume_state = hass.states.get("sensor.ingress_mic_volume")
assert ingress_mic_volume_state.state == "11"
ingress_doorbell_volume_state = hass.states.get("sensor.ingress_doorbell_volume")
assert ingress_doorbell_volume_state.state == "8"
ingress_voice_volume_state = hass.states.get("sensor.ingress_voice_volume")
assert ingress_voice_volume_state.state == "11"
@pytest.mark.parametrize(
("device_id", "device_name", "sensor_name", "expected_value"),
[
(987654, "front_door", "wifi_signal_category", "good"),
(987654, "front_door", "wifi_signal_strength", "-58"),
(123456, "downstairs", "wifi_signal_category", "good"),
(123456, "downstairs", "wifi_signal_strength", "-39"),
(765432, "front", "wifi_signal_category", "good"),
(765432, "front", "wifi_signal_strength", "-58"),
],
ids=[
"doorbell-category",
"doorbell-strength",
"chime-category",
"chime-strength",
"stickup_cam-category",
"stickup_cam-strength",
],
)
async def test_health_sensor(
hass: HomeAssistant,
mock_ring_client,
freezer: FrozenDateTimeFactory,
entity_registry: er.EntityRegistry,
device_id,
device_name,
sensor_name,
expected_value,
) -> None:
"""Test the Ring health sensors."""
entity_id = f"sensor.{device_name}_{sensor_name}"
# Enable the sensor as the health sensors are disabled by default
entity_entry = entity_registry.async_get_or_create(
"sensor",
"ring",
f"{device_id}-{sensor_name}",
suggested_object_id=f"{device_name}_{sensor_name}",
disabled_by=None,
)
assert entity_entry.disabled is False
assert entity_entry.entity_id == entity_id
await setup_platform(hass, "sensor")
await hass.async_block_till_done()
sensor_state = hass.states.get(entity_id)
assert sensor_state is not None
assert sensor_state.state == "unknown"
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
sensor_state = hass.states.get(entity_id)
assert sensor_state is not None
assert sensor_state.state == expected_value
@pytest.mark.parametrize(
("device_id", "device_name", "sensor_name", "expected_value"),
[
(
FRONT_DOOR_DEVICE_ID,
"front_door",
"last_motion",
"2017-03-05T15:03:40+00:00",
),
(FRONT_DOOR_DEVICE_ID, "front_door", "last_ding", "2018-03-05T15:03:40+00:00"),
(
FRONT_DOOR_DEVICE_ID,
"front_door",
"last_activity",
"2018-03-05T15:03:40+00:00",
),
(FRONT_DEVICE_ID, "front", "last_motion", "2017-03-05T15:03:40+00:00"),
(INGRESS_DEVICE_ID, "ingress", "last_activity", "2024-02-02T11:21:24+00:00"),
],
ids=[
"doorbell-motion",
"doorbell-ding",
"doorbell-activity",
"stickup_cam-motion",
"other-activity",
],
)
async def test_history_sensor(
hass: HomeAssistant,
mock_ring_client: Ring,
mock_config_entry: ConfigEntry,
entity_registry: er.EntityRegistry,
freezer: FrozenDateTimeFactory,
device_id: int,
device_name: str,
sensor_name: str,
expected_value: str,
) -> None:
"""Test the Ring sensors."""
# Create the entity so it is not ignored by the deprecation check
mock_config_entry.add_to_hass(hass)
entity_id = f"sensor.{device_name}_{sensor_name}"
unique_id = f"{device_id}-{sensor_name}"
entity_registry.async_get_or_create(
domain=SENSOR_DOMAIN,
platform=DOMAIN,
unique_id=unique_id,
suggested_object_id=f"{device_name}_{sensor_name}",
config_entry=mock_config_entry,
)
with patch("homeassistant.components.ring.PLATFORMS", [Platform.SENSOR]):
assert await async_setup_component(hass, DOMAIN, {})
entity_id = f"sensor.{device_name}_{sensor_name}"
sensor_state = hass.states.get(entity_id)
assert sensor_state is not None
assert sensor_state.state == "unknown"
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
sensor_state = hass.states.get(entity_id)
assert sensor_state is not None
assert sensor_state.state == expected_value
async def test_only_chime_devices(
hass: HomeAssistant,
mock_ring_client,
mock_ring_devices,
freezer: FrozenDateTimeFactory,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Tests the update service works correctly if only chimes are returned."""
await hass.config.async_set_time_zone("UTC")
freezer.move_to("2021-01-09 12:00:00+00:00")
mock_ring_devices.all_devices = mock_ring_devices.chimes
await setup_platform(hass, Platform.SENSOR)
await hass.async_block_till_done()
caplog.set_level(logging.DEBUG)
caplog.clear()
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert "UnboundLocalError" not in caplog.text # For issue #109210