Files
ha-ninlight/tests/test_sensor.py
T
Michael Sauer 83618b19fd feat: IP-Adresse standardmaessig als Entitaet aktiv
Die IP ist der Wert, den man beim Suchen einer Lampe zuerst braucht - als
abgeschaltete Diagnose-Entitaet war sie genau dann nicht da.
2026-09-22 23:20:14 +02:00

85 lines
3.6 KiB
Python

"""Diagnostic sensors."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
from freezegun.api import FrozenDateTimeFactory
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from pytest_homeassistant_custom_component.common import MockConfigEntry, async_fire_time_changed
from tests.helpers import entity_id_for
DISABLED_KEYS = ("free_heap", "last_ota_error", "boot_time")
async def _enable_all(
hass: HomeAssistant, entry: MockConfigEntry, freezer: FrozenDateTimeFactory
) -> None:
registry = er.async_get(hass)
for key in DISABLED_KEYS:
registry.async_update_entity(entity_id_for(hass, "sensor", key), disabled_by=None)
await hass.config_entries.async_reload(entry.entry_id)
await hass.async_block_till_done()
# HA 2026.9: registry.async_update_entity(disabled_by=None) also arms the config entry's
# own debounced reload (config_entries.RELOAD_AFTER_UPDATE_DELAY = 30 s), independent of
# the explicit reload above. Left alone, that second reload fires mid-test - typically
# right on top of the first _poll() below - and silently replaces the boot-time entity,
# defeating the jitter-tolerance assertion. Drain it here so the entities are settled
# before the test takes its "first" reading.
freezer.tick(timedelta(seconds=31))
async_fire_time_changed(hass)
await hass.async_block_till_done()
async def _poll(hass: HomeAssistant, freezer: FrozenDateTimeFactory, seconds: int) -> None:
freezer.tick(timedelta(seconds=seconds))
async_fire_time_changed(hass)
await hass.async_block_till_done()
async def test_signal_and_ip_enabled_others_disabled_by_default(
hass: HomeAssistant, init_integration
) -> None:
registry = er.async_get(hass)
assert hass.states.get(entity_id_for(hass, "sensor", "rssi")).state == "-61"
assert hass.states.get(entity_id_for(hass, "sensor", "ip_address")).state == "192.168.2.22"
for key in DISABLED_KEYS:
entry = registry.async_get(entity_id_for(hass, "sensor", key))
assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION, key
async def test_diagnostic_values(
hass: HomeAssistant, init_integration: MockConfigEntry, freezer
) -> None:
await _enable_all(hass, init_integration, freezer)
assert hass.states.get(entity_id_for(hass, "sensor", "ip_address")).state == "192.168.2.22"
assert hass.states.get(entity_id_for(hass, "sensor", "free_heap")).state == "119872"
assert hass.states.get(entity_id_for(hass, "sensor", "last_ota_error")).state == "unknown"
expected_boot = dt_util.utcnow() - timedelta(seconds=129832)
boot = dt_util.parse_datetime(hass.states.get(entity_id_for(hass, "sensor", "boot_time")).state)
assert abs((boot - expected_boot).total_seconds()) < 2
async def test_boot_time_ignores_jitter_but_follows_reboots(
hass: HomeAssistant,
init_integration: MockConfigEntry,
lamp_info: dict[str, Any],
freezer: FrozenDateTimeFactory,
) -> None:
await _enable_all(hass, init_integration, freezer)
entity_id = entity_id_for(hass, "sensor", "boot_time")
first = hass.states.get(entity_id).state
lamp_info["uptime"] += 31 + 20 # clock drift of 20 s: below the 60 s threshold
await _poll(hass, freezer, 31)
assert hass.states.get(entity_id).state == first
lamp_info["uptime"] = 12 # the lamp rebooted
await _poll(hass, freezer, 31)
rebooted = dt_util.parse_datetime(hass.states.get(entity_id).state)
assert abs((rebooted - (dt_util.utcnow() - timedelta(seconds=12))).total_seconds()) < 2