From e209f3723e61231867b3020774a8cb6b24591b8c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 15 Aug 2023 09:29:25 -0500 Subject: [PATCH] Restore sensorpush state when device becomes available (#98420) --- homeassistant/components/sensorpush/sensor.py | 4 +- tests/components/sensorpush/__init__.py | 11 ++++ tests/components/sensorpush/test_sensor.py | 60 ++++++++++++++++--- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/sensorpush/sensor.py b/homeassistant/components/sensorpush/sensor.py index 479acd8ac1e..e12bf0e48c6 100644 --- a/homeassistant/components/sensorpush/sensor.py +++ b/homeassistant/components/sensorpush/sensor.py @@ -110,7 +110,9 @@ async def async_setup_entry( SensorPushBluetoothSensorEntity, async_add_entities ) ) - entry.async_on_unload(coordinator.async_register_processor(processor)) + entry.async_on_unload( + coordinator.async_register_processor(processor, SensorEntityDescription) + ) class SensorPushBluetoothSensorEntity( diff --git a/tests/components/sensorpush/__init__.py b/tests/components/sensorpush/__init__.py index 0fe9ced64df..c281d4dc086 100644 --- a/tests/components/sensorpush/__init__.py +++ b/tests/components/sensorpush/__init__.py @@ -32,3 +32,14 @@ HTPWX_SERVICE_INFO = BluetoothServiceInfo( service_uuids=["ef090000-11d6-42ba-93b8-9dd7ec090ab0"], source="local", ) + + +HTPWX_EMPTY_SERVICE_INFO = BluetoothServiceInfo( + name="SensorPush HTP.xw F4D", + address="4125DDBA-2774-4851-9889-6AADDD4CAC3D", + rssi=-56, + manufacturer_data={}, + service_data={}, + service_uuids=["ef090000-11d6-42ba-93b8-9dd7ec090ab0"], + source="local", +) diff --git a/tests/components/sensorpush/test_sensor.py b/tests/components/sensorpush/test_sensor.py index f2d6cf6d1ac..e00b626b20b 100644 --- a/tests/components/sensorpush/test_sensor.py +++ b/tests/components/sensorpush/test_sensor.py @@ -1,17 +1,33 @@ """Test the SensorPush sensors.""" +from datetime import timedelta +import time +from unittest.mock import patch + +from homeassistant.components.bluetooth import ( + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS, +) from homeassistant.components.sensor import ATTR_STATE_CLASS from homeassistant.components.sensorpush.const import DOMAIN -from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT +from homeassistant.const import ( + ATTR_FRIENDLY_NAME, + ATTR_UNIT_OF_MEASUREMENT, + STATE_UNAVAILABLE, +) from homeassistant.core import HomeAssistant +from homeassistant.util import dt as dt_util -from . import HTPWX_SERVICE_INFO +from . import HTPWX_EMPTY_SERVICE_INFO, HTPWX_SERVICE_INFO -from tests.common import MockConfigEntry -from tests.components.bluetooth import inject_bluetooth_service_info +from tests.common import MockConfigEntry, async_fire_time_changed +from tests.components.bluetooth import ( + inject_bluetooth_service_info, + patch_all_discovered_devices, +) async def test_sensors(hass: HomeAssistant) -> None: """Test setting up creates the sensors.""" + start_monotonic = time.monotonic() entry = MockConfigEntry( domain=DOMAIN, unique_id="4125DDBA-2774-4851-9889-6AADDD4CAC3D", @@ -27,11 +43,39 @@ async def test_sensors(hass: HomeAssistant) -> None: assert len(hass.states.async_all()) == 3 temp_sensor = hass.states.get("sensor.htp_xw_f4d_temperature") - temp_sensor_attribtes = temp_sensor.attributes + temp_sensor_attributes = temp_sensor.attributes + assert temp_sensor.state == "20.11" + assert temp_sensor_attributes[ATTR_FRIENDLY_NAME] == "HTP.xw F4D Temperature" + assert temp_sensor_attributes[ATTR_UNIT_OF_MEASUREMENT] == "°C" + assert temp_sensor_attributes[ATTR_STATE_CLASS] == "measurement" + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + + # Fastforward time without BLE advertisements + monotonic_now = start_monotonic + FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1 + + with patch( + "homeassistant.components.bluetooth.manager.MONOTONIC_TIME", + return_value=monotonic_now, + ), patch_all_discovered_devices([]): + async_fire_time_changed( + hass, + dt_util.utcnow() + + timedelta(seconds=FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS + 1), + ) + await hass.async_block_till_done() + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + temp_sensor = hass.states.get("sensor.htp_xw_f4d_temperature") + assert temp_sensor.state == STATE_UNAVAILABLE + inject_bluetooth_service_info(hass, HTPWX_EMPTY_SERVICE_INFO) + await hass.async_block_till_done() + + temp_sensor = hass.states.get("sensor.htp_xw_f4d_temperature") assert temp_sensor.state == "20.11" - assert temp_sensor_attribtes[ATTR_FRIENDLY_NAME] == "HTP.xw F4D Temperature" - assert temp_sensor_attribtes[ATTR_UNIT_OF_MEASUREMENT] == "°C" - assert temp_sensor_attribtes[ATTR_STATE_CLASS] == "measurement" assert await hass.config_entries.async_unload(entry.entry_id) await hass.async_block_till_done()