Adjust generic hygrostat to detect reported events for stale tracking (#124109)
* Listen to reported events for stale check * Always enable stale sensor tracking There is no reason not to have this enabled now that we track reported events for sensors. * Remove default stale code * Adjust for ruff changepull/125006/head^2
parent
e7cb646a58
commit
3139a7e431
|
@ -36,6 +36,7 @@ from homeassistant.core import (
|
|||
DOMAIN as HOMEASSISTANT_DOMAIN,
|
||||
Event,
|
||||
EventStateChangedData,
|
||||
EventStateReportedData,
|
||||
HomeAssistant,
|
||||
State,
|
||||
callback,
|
||||
|
@ -45,6 +46,7 @@ from homeassistant.helpers.device import async_device_info_to_link_from_entity
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
async_track_state_report_event,
|
||||
async_track_time_interval,
|
||||
)
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
|
@ -72,7 +74,6 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
ATTR_SAVED_HUMIDITY = "saved_humidity"
|
||||
|
||||
|
||||
PLATFORM_SCHEMA = HUMIDIFIER_PLATFORM_SCHEMA.extend(HYGROSTAT_SCHEMA.schema)
|
||||
|
||||
|
||||
|
@ -222,18 +223,21 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||
"""Run when entity about to be added."""
|
||||
await super().async_added_to_hass()
|
||||
|
||||
# Add listener
|
||||
self.async_on_remove(
|
||||
async_track_state_change_event(
|
||||
self.hass, self._sensor_entity_id, self._async_sensor_changed_event
|
||||
self.hass, self._sensor_entity_id, self._async_sensor_event
|
||||
)
|
||||
)
|
||||
self.async_on_remove(
|
||||
async_track_state_report_event(
|
||||
self.hass, self._sensor_entity_id, self._async_sensor_event
|
||||
)
|
||||
)
|
||||
self.async_on_remove(
|
||||
async_track_state_change_event(
|
||||
self.hass, self._switch_entity_id, self._async_switch_changed_event
|
||||
self.hass, self._switch_entity_id, self._async_switch_event
|
||||
)
|
||||
)
|
||||
|
||||
if self._keep_alive:
|
||||
self.async_on_remove(
|
||||
async_track_time_interval(
|
||||
|
@ -253,7 +257,8 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||
sensor_state.state if sensor_state is not None else "None",
|
||||
)
|
||||
return
|
||||
await self._async_sensor_changed(self._sensor_entity_id, None, sensor_state)
|
||||
|
||||
await self._async_sensor_update(sensor_state)
|
||||
|
||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, _async_startup)
|
||||
|
||||
|
@ -391,25 +396,23 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||
# Get default humidity from super class
|
||||
return super().max_humidity
|
||||
|
||||
async def _async_sensor_changed_event(
|
||||
self, event: Event[EventStateChangedData]
|
||||
) -> None:
|
||||
"""Handle ambient humidity changes."""
|
||||
data = event.data
|
||||
await self._async_sensor_changed(
|
||||
data["entity_id"], data["old_state"], data["new_state"]
|
||||
)
|
||||
|
||||
async def _async_sensor_changed(
|
||||
self, entity_id: str, old_state: State | None, new_state: State | None
|
||||
async def _async_sensor_event(
|
||||
self, event: Event[EventStateChangedData] | Event[EventStateReportedData]
|
||||
) -> None:
|
||||
"""Handle ambient humidity changes."""
|
||||
new_state = event.data["new_state"]
|
||||
if new_state is None:
|
||||
return
|
||||
|
||||
await self._async_sensor_update(new_state)
|
||||
|
||||
async def _async_sensor_update(self, new_state: State) -> None:
|
||||
"""Update state based on humidity sensor."""
|
||||
|
||||
if self._sensor_stale_duration:
|
||||
if self._remove_stale_tracking:
|
||||
self._remove_stale_tracking()
|
||||
|
||||
self._remove_stale_tracking = async_track_time_interval(
|
||||
self.hass,
|
||||
self._async_sensor_not_responding,
|
||||
|
@ -426,23 +429,18 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||
state = self.hass.states.get(self._sensor_entity_id)
|
||||
_LOGGER.debug(
|
||||
"Sensor has not been updated for %s",
|
||||
now - state.last_updated if now and state else "---",
|
||||
now - state.last_reported if now and state else "---",
|
||||
)
|
||||
_LOGGER.warning("Sensor is stalled, call the emergency stop")
|
||||
await self._async_update_humidity("Stalled")
|
||||
|
||||
@callback
|
||||
def _async_switch_changed_event(self, event: Event[EventStateChangedData]) -> None:
|
||||
def _async_switch_event(self, event: Event[EventStateChangedData]) -> None:
|
||||
"""Handle humidifier switch state changes."""
|
||||
data = event.data
|
||||
self._async_switch_changed(
|
||||
data["entity_id"], data["old_state"], data["new_state"]
|
||||
)
|
||||
self._async_switch_changed(event.data["new_state"])
|
||||
|
||||
@callback
|
||||
def _async_switch_changed(
|
||||
self, entity_id: str, old_state: State | None, new_state: State | None
|
||||
) -> None:
|
||||
def _async_switch_changed(self, new_state: State | None) -> None:
|
||||
"""Handle humidifier switch state changes."""
|
||||
if new_state is None:
|
||||
return
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import datetime
|
||||
|
||||
from freezegun import freeze_time
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -520,6 +521,7 @@ async def test_set_target_humidity_humidifier_on(hass: HomeAssistant) -> None:
|
|||
calls = await _setup_switch(hass, False)
|
||||
_setup_sensor(hass, 36)
|
||||
await hass.async_block_till_done()
|
||||
calls.clear()
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_HUMIDITY,
|
||||
|
@ -540,6 +542,7 @@ async def test_set_target_humidity_humidifier_off(hass: HomeAssistant) -> None:
|
|||
calls = await _setup_switch(hass, True)
|
||||
_setup_sensor(hass, 45)
|
||||
await hass.async_block_till_done()
|
||||
calls.clear()
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_HUMIDITY,
|
||||
|
@ -1733,7 +1736,9 @@ async def test_away_fixed_humidity_mode(hass: HomeAssistant) -> None:
|
|||
|
||||
@pytest.mark.usefixtures("setup_comp_1")
|
||||
async def test_sensor_stale_duration(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test turn off on sensor stale."""
|
||||
|
||||
|
@ -1775,14 +1780,31 @@ async def test_sensor_stale_duration(
|
|||
assert hass.states.get(humidifier_switch).state == STATE_ON
|
||||
|
||||
# Wait 11 minutes
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(minutes=11))
|
||||
freezer.tick(datetime.timedelta(minutes=11))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# 11 minutes later, no news from the sensor : emergency cut off
|
||||
assert hass.states.get(humidifier_switch).state == STATE_OFF
|
||||
assert "emergency" in caplog.text
|
||||
|
||||
# Updated value from sensor received
|
||||
# Updated value from sensor received (same value)
|
||||
_setup_sensor(hass, 23)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# A new value has arrived, the humidifier should go ON
|
||||
assert hass.states.get(humidifier_switch).state == STATE_ON
|
||||
|
||||
# Wait 11 minutes
|
||||
freezer.tick(datetime.timedelta(minutes=11))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# 11 minutes later, no news from the sensor : emergency cut off
|
||||
assert hass.states.get(humidifier_switch).state == STATE_OFF
|
||||
assert "emergency" in caplog.text
|
||||
|
||||
# Updated value from sensor received (new value)
|
||||
_setup_sensor(hass, 24)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
|
Loading…
Reference in New Issue