mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
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 change
This commit is contained in:
parent
e7cb646a58
commit
3139a7e431
@ -36,6 +36,7 @@ from homeassistant.core import (
|
|||||||
DOMAIN as HOMEASSISTANT_DOMAIN,
|
DOMAIN as HOMEASSISTANT_DOMAIN,
|
||||||
Event,
|
Event,
|
||||||
EventStateChangedData,
|
EventStateChangedData,
|
||||||
|
EventStateReportedData,
|
||||||
HomeAssistant,
|
HomeAssistant,
|
||||||
State,
|
State,
|
||||||
callback,
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.event import (
|
from homeassistant.helpers.event import (
|
||||||
async_track_state_change_event,
|
async_track_state_change_event,
|
||||||
|
async_track_state_report_event,
|
||||||
async_track_time_interval,
|
async_track_time_interval,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.restore_state import RestoreEntity
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
@ -72,7 +74,6 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
ATTR_SAVED_HUMIDITY = "saved_humidity"
|
ATTR_SAVED_HUMIDITY = "saved_humidity"
|
||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = HUMIDIFIER_PLATFORM_SCHEMA.extend(HYGROSTAT_SCHEMA.schema)
|
PLATFORM_SCHEMA = HUMIDIFIER_PLATFORM_SCHEMA.extend(HYGROSTAT_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
@ -222,18 +223,21 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||||||
"""Run when entity about to be added."""
|
"""Run when entity about to be added."""
|
||||||
await super().async_added_to_hass()
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
# Add listener
|
|
||||||
self.async_on_remove(
|
self.async_on_remove(
|
||||||
async_track_state_change_event(
|
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(
|
self.async_on_remove(
|
||||||
async_track_state_change_event(
|
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:
|
if self._keep_alive:
|
||||||
self.async_on_remove(
|
self.async_on_remove(
|
||||||
async_track_time_interval(
|
async_track_time_interval(
|
||||||
@ -253,7 +257,8 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||||||
sensor_state.state if sensor_state is not None else "None",
|
sensor_state.state if sensor_state is not None else "None",
|
||||||
)
|
)
|
||||||
return
|
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)
|
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
|
# Get default humidity from super class
|
||||||
return super().max_humidity
|
return super().max_humidity
|
||||||
|
|
||||||
async def _async_sensor_changed_event(
|
async def _async_sensor_event(
|
||||||
self, event: Event[EventStateChangedData]
|
self, event: Event[EventStateChangedData] | Event[EventStateReportedData]
|
||||||
) -> 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
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Handle ambient humidity changes."""
|
"""Handle ambient humidity changes."""
|
||||||
|
new_state = event.data["new_state"]
|
||||||
if new_state is None:
|
if new_state is None:
|
||||||
return
|
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._sensor_stale_duration:
|
||||||
if self._remove_stale_tracking:
|
if self._remove_stale_tracking:
|
||||||
self._remove_stale_tracking()
|
self._remove_stale_tracking()
|
||||||
|
|
||||||
self._remove_stale_tracking = async_track_time_interval(
|
self._remove_stale_tracking = async_track_time_interval(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._async_sensor_not_responding,
|
self._async_sensor_not_responding,
|
||||||
@ -426,23 +429,18 @@ class GenericHygrostat(HumidifierEntity, RestoreEntity):
|
|||||||
state = self.hass.states.get(self._sensor_entity_id)
|
state = self.hass.states.get(self._sensor_entity_id)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Sensor has not been updated for %s",
|
"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")
|
_LOGGER.warning("Sensor is stalled, call the emergency stop")
|
||||||
await self._async_update_humidity("Stalled")
|
await self._async_update_humidity("Stalled")
|
||||||
|
|
||||||
@callback
|
@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."""
|
"""Handle humidifier switch state changes."""
|
||||||
data = event.data
|
self._async_switch_changed(event.data["new_state"])
|
||||||
self._async_switch_changed(
|
|
||||||
data["entity_id"], data["old_state"], data["new_state"]
|
|
||||||
)
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_switch_changed(
|
def _async_switch_changed(self, new_state: State | None) -> None:
|
||||||
self, entity_id: str, old_state: State | None, new_state: State | None
|
|
||||||
) -> None:
|
|
||||||
"""Handle humidifier switch state changes."""
|
"""Handle humidifier switch state changes."""
|
||||||
if new_state is None:
|
if new_state is None:
|
||||||
return
|
return
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
import voluptuous as vol
|
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)
|
calls = await _setup_switch(hass, False)
|
||||||
_setup_sensor(hass, 36)
|
_setup_sensor(hass, 36)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
calls.clear()
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_SET_HUMIDITY,
|
SERVICE_SET_HUMIDITY,
|
||||||
@ -540,6 +542,7 @@ async def test_set_target_humidity_humidifier_off(hass: HomeAssistant) -> None:
|
|||||||
calls = await _setup_switch(hass, True)
|
calls = await _setup_switch(hass, True)
|
||||||
_setup_sensor(hass, 45)
|
_setup_sensor(hass, 45)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
calls.clear()
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_SET_HUMIDITY,
|
SERVICE_SET_HUMIDITY,
|
||||||
@ -1733,7 +1736,9 @@ async def test_away_fixed_humidity_mode(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
@pytest.mark.usefixtures("setup_comp_1")
|
@pytest.mark.usefixtures("setup_comp_1")
|
||||||
async def test_sensor_stale_duration(
|
async def test_sensor_stale_duration(
|
||||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test turn off on sensor stale."""
|
"""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
|
assert hass.states.get(humidifier_switch).state == STATE_ON
|
||||||
|
|
||||||
# Wait 11 minutes
|
# 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()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# 11 minutes later, no news from the sensor : emergency cut off
|
# 11 minutes later, no news from the sensor : emergency cut off
|
||||||
assert hass.states.get(humidifier_switch).state == STATE_OFF
|
assert hass.states.get(humidifier_switch).state == STATE_OFF
|
||||||
assert "emergency" in caplog.text
|
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)
|
_setup_sensor(hass, 24)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user