mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 07:51:46 -05:00
Poll the myStrom motion sensor readings (#180416)
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
"""Support for myStrom sensors of switches/plugs."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from collections.abc import Callable, Coroutine
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
from typing import Any, override
|
||||
|
||||
from pymystrom.exceptions import MyStromConnectionError
|
||||
from pymystrom.pir import MyStromPir
|
||||
from pymystrom.switch import MyStromSwitch
|
||||
|
||||
@@ -29,12 +31,17 @@ from homeassistant.util.dt import utcnow
|
||||
from .const import DOMAIN, MANUFACTURER
|
||||
from .models import MyStromConfigEntry
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class MyStromSensorEntityDescription[_DeviceT](SensorEntityDescription):
|
||||
"""Class describing mystrom sensor entities."""
|
||||
|
||||
value_fn: Callable[[_DeviceT], float | None]
|
||||
# Only needed where nothing else on the device polls; a switch is kept
|
||||
# fresh by its own entity refreshing the shared device.
|
||||
update_fn: Callable[[_DeviceT], Coroutine[Any, Any, None]] | None = None
|
||||
|
||||
|
||||
SENSOR_TYPES_PIR: tuple[MyStromSensorEntityDescription[MyStromPir], ...] = (
|
||||
@@ -50,6 +57,7 @@ SENSOR_TYPES_PIR: tuple[MyStromSensorEntityDescription[MyStromPir], ...] = (
|
||||
else None
|
||||
)
|
||||
),
|
||||
update_fn=lambda device: device.get_temperatures(),
|
||||
),
|
||||
MyStromSensorEntityDescription(
|
||||
key="illuminance",
|
||||
@@ -61,6 +69,7 @@ SENSOR_TYPES_PIR: tuple[MyStromSensorEntityDescription[MyStromPir], ...] = (
|
||||
float(device.intensity) if device.intensity is not None else None
|
||||
)
|
||||
),
|
||||
update_fn=lambda device: device.get_light(),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -180,6 +189,20 @@ class MyStromSensor[_DeviceT](MyStromSensorBase):
|
||||
"""Return the value of the sensor."""
|
||||
return self.entity_description.value_fn(self.device)
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Get the latest reading from the device."""
|
||||
if (update_fn := self.entity_description.update_fn) is None:
|
||||
return
|
||||
|
||||
try:
|
||||
await update_fn(self.device)
|
||||
except MyStromConnectionError:
|
||||
if self.available:
|
||||
self._attr_available = False
|
||||
_LOGGER.error("No route to myStrom device")
|
||||
else:
|
||||
self._attr_available = True
|
||||
|
||||
|
||||
class MyStromSwitchUptimeSensor(MyStromSensorBase):
|
||||
"""Representation of a MyStrom Switch uptime sensor."""
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Test the myStrom sensors."""
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .test_init import init_integration
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
async def test_pir_sensors_are_polled(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test the motion sensor readings are refreshed while polling."""
|
||||
await init_integration(hass, config_entry, 110)
|
||||
|
||||
device = config_entry.runtime_data.device
|
||||
assert hass.states.get("sensor.mystrom_device_temperature").state == "24.87"
|
||||
assert hass.states.get("sensor.mystrom_device_illuminance").state == "16.0"
|
||||
|
||||
# The mock only reports readings once they have been fetched, and nothing
|
||||
# else talks to a motion sensor, so this stays cleared unless the sensors
|
||||
# fetch them themselves.
|
||||
device._requested_state = False
|
||||
device._state["temperature_compensated"] = 21.5
|
||||
device._state["intensity"] = 42
|
||||
|
||||
freezer.tick(timedelta(minutes=5))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert device._requested_state is True
|
||||
assert hass.states.get("sensor.mystrom_device_temperature").state == "21.5"
|
||||
assert hass.states.get("sensor.mystrom_device_illuminance").state == "42.0"
|
||||
Reference in New Issue
Block a user