diff --git a/homeassistant/components/watts/const.py b/homeassistant/components/watts/const.py index e1ba4a0134e0..8002762467fa 100644 --- a/homeassistant/components/watts/const.py +++ b/homeassistant/components/watts/const.py @@ -23,7 +23,7 @@ OAUTH2_SCOPES = [ # Update intervals UPDATE_INTERVAL_SECONDS = 30 FAST_POLLING_INTERVAL_SECONDS = 5 -DISCOVERY_INTERVAL_MINUTES = 15 +DISCOVERY_INTERVAL_SECONDS = 15 * 60 # Mapping from Watts Vision+ modes to Home Assistant HVAC modes THERMOSTAT_MODE_TO_HVAC: dict[ThermostatMode, HVACMode] = { diff --git a/homeassistant/components/watts/coordinator.py b/homeassistant/components/watts/coordinator.py index 754e268d8c90..28982b63ec05 100644 --- a/homeassistant/components/watts/coordinator.py +++ b/homeassistant/components/watts/coordinator.py @@ -1,8 +1,9 @@ """Data coordinator for Watts Vision integration.""" from dataclasses import dataclass -from datetime import datetime, timedelta +from datetime import timedelta import logging +import time from typing import TYPE_CHECKING, override from visionpluspython.client import WattsVisionClient @@ -22,7 +23,7 @@ from homeassistant.helpers import device_registry as dr from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import ( - DISCOVERY_INTERVAL_MINUTES, + DISCOVERY_INTERVAL_SECONDS, DOMAIN, FAST_POLLING_INTERVAL_SECONDS, UPDATE_INTERVAL_SECONDS, @@ -61,18 +62,17 @@ class WattsVisionHubCoordinator(DataUpdateCoordinator[dict[str, Device]]): config_entry=config_entry, ) self.client = client - self.last_discovery: datetime | None = None + self.last_discovery: float | None = None self.previous_devices: set[str] = set() @override async def _async_update_data(self) -> dict[str, Device]: """Fetch data and periodic device discovery.""" - now = datetime.now() # pylint: disable=home-assistant-enforce-naive-now + now = time.time() is_first_refresh = self.last_discovery is None discovery_interval_elapsed = ( self.last_discovery is not None - and now - self.last_discovery - >= timedelta(minutes=DISCOVERY_INTERVAL_MINUTES) + and now - self.last_discovery >= DISCOVERY_INTERVAL_SECONDS ) if is_first_refresh or discovery_interval_elapsed: @@ -185,7 +185,7 @@ class WattsVisionDeviceCoordinator(DataUpdateCoordinator[WattsVisionDeviceData]) self.client = client self.device_id = device_id self.hub_coordinator = hub_coordinator - self.fast_polling_until: datetime | None = None + self.fast_polling_until: float | None = None # Listen to hub coordinator updates self.unsubscribe_hub_listener = hub_coordinator.async_add_listener( @@ -208,7 +208,7 @@ class WattsVisionDeviceCoordinator(DataUpdateCoordinator[WattsVisionDeviceData]) @override async def _async_update_data(self) -> WattsVisionDeviceData: """Refresh specific device.""" - if self.fast_polling_until and datetime.now() > self.fast_polling_until: # pylint: disable=home-assistant-enforce-naive-now + if self.fast_polling_until and time.time() > self.fast_polling_until: self.fast_polling_until = None self.update_interval = None _LOGGER.debug( @@ -244,10 +244,12 @@ class WattsVisionDeviceCoordinator(DataUpdateCoordinator[WattsVisionDeviceData]) _LOGGER.debug("Refreshed device %s", self.device_id) return WattsVisionDeviceData(device=device) - def trigger_fast_polling(self, duration: int = 60) -> None: + def trigger_fast_polling(self, duration_seconds: int = 60) -> None: """Activate fast polling for a specified duration after a command.""" - self.fast_polling_until = datetime.now() + timedelta(seconds=duration) # pylint: disable=home-assistant-enforce-naive-now + self.fast_polling_until = time.time() + duration_seconds self.update_interval = timedelta(seconds=FAST_POLLING_INTERVAL_SECONDS) _LOGGER.debug( - "Device %s: Activated fast polling for %d seconds", self.device_id, duration + "Device %s: Activated fast polling for %d seconds", + self.device_id, + duration_seconds, ) diff --git a/homeassistant/components/watts/diagnostics.py b/homeassistant/components/watts/diagnostics.py index ece46d9cf79a..53b94c54bf97 100644 --- a/homeassistant/components/watts/diagnostics.py +++ b/homeassistant/components/watts/diagnostics.py @@ -1,12 +1,13 @@ """Diagnostics support for Watts Vision +.""" import dataclasses -from datetime import datetime +import time from typing import Any from homeassistant.components.diagnostics import async_redact_data from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant +from homeassistant.util import dt as dt_util from . import WattsVisionConfigEntry @@ -21,7 +22,7 @@ async def async_get_config_entry_diagnostics( runtime_data = entry.runtime_data hub_coordinator = runtime_data.hub_coordinator device_coordinators = runtime_data.device_coordinators - now = datetime.now() # pylint: disable=home-assistant-enforce-naive-now + now = time.time() return async_redact_data( { @@ -34,7 +35,9 @@ async def async_get_config_entry_diagnostics( else None ), "last_discovery": ( - hub_coordinator.last_discovery.isoformat() + dt_util.utc_from_timestamp( + hub_coordinator.last_discovery + ).isoformat() if hub_coordinator.last_discovery else None ), @@ -54,7 +57,9 @@ async def async_get_config_entry_diagnostics( and coordinator.fast_polling_until > now ), "fast_polling_until": ( - coordinator.fast_polling_until.isoformat() + dt_util.utc_from_timestamp( + coordinator.fast_polling_until + ).isoformat() if coordinator.fast_polling_until is not None and coordinator.fast_polling_until > now else None diff --git a/tests/components/watts/snapshots/test_diagnostics.ambr b/tests/components/watts/snapshots/test_diagnostics.ambr index 072c4181dc59..ffc330f17add 100644 --- a/tests/components/watts/snapshots/test_diagnostics.ambr +++ b/tests/components/watts/snapshots/test_diagnostics.ambr @@ -102,7 +102,7 @@ 'version': 1, }), 'hub_coordinator': dict({ - 'last_discovery': '2026-01-01T12:00:00', + 'last_discovery': '2026-01-01T12:00:00+00:00', 'last_exception': None, 'last_update_success': True, 'supported_devices': 3, diff --git a/tests/components/watts/test_init.py b/tests/components/watts/test_init.py index acca220ce125..2044e5cedd23 100644 --- a/tests/components/watts/test_init.py +++ b/tests/components/watts/test_init.py @@ -21,7 +21,7 @@ from homeassistant.components.climate import ( SERVICE_SET_TEMPERATURE, ) from homeassistant.components.watts.const import ( - DISCOVERY_INTERVAL_MINUTES, + DISCOVERY_INTERVAL_SECONDS, DOMAIN, FAST_POLLING_INTERVAL_SECONDS, OAUTH2_TOKEN, @@ -230,7 +230,7 @@ async def test_dynamic_device_creation( current_devices = list(mock_watts_client.discover_devices.return_value) mock_watts_client.discover_devices.return_value = [*current_devices, new_device] - freezer.tick(timedelta(minutes=DISCOVERY_INTERVAL_MINUTES)) + freezer.tick(timedelta(seconds=DISCOVERY_INTERVAL_SECONDS)) async_fire_time_changed(hass) await hass.async_block_till_done() @@ -270,7 +270,7 @@ async def test_stale_device_removal( d for d in current_devices if d.device_id != "thermostat_456" ] - freezer.tick(timedelta(minutes=DISCOVERY_INTERVAL_MINUTES)) + freezer.tick(timedelta(seconds=DISCOVERY_INTERVAL_SECONDS)) async_fire_time_changed(hass) await hass.async_block_till_done()