44
55import async_timeout
66
7- from homeassistant .core import HomeAssistant
7+ from homeassistant .core import HomeAssistant , callback
88from homeassistant .helpers .update_coordinator import DataUpdateCoordinator , UpdateFailed
99from homeassistant .util import Throttle
10- from homeassistant .helpers .event import async_track_time_interval
10+ from homeassistant .helpers .event import async_call_later , async_track_time_interval
1111
1212from .rinnai import WaterHeater
1313
@@ -35,7 +35,9 @@ def __init__(
3535 self ._device_info : Optional [Dict [str , Any ]] | None = None
3636 self .options = options
3737 self .maint_refresh_interval = timedelta (seconds = self .options .get (CONF_MAINT_REFRESH_INTERVAL , DEFAULT_MAINT_REFRESH_INTERVAL ))
38- self ._unsub_maintenance_timer = None # Track the maintenance timer
38+ self ._unsub_maintenance_timer = None # Track the recurring maintenance timer
39+ self ._unsub_maintenance_delay = None # Track the initial delay timer
40+ self ._maintenance_enabled = self .options .get (CONF_MAINT_INTERVAL_ENABLED , False )
3941 super ().__init__ (
4042 hass ,
4143 LOGGER ,
@@ -397,33 +399,79 @@ async def async_do_maintenance_retrieval(self, _event=None):
397399 async def _update_device (self , * _ ) -> None :
398400 """Update the device information from the API"""
399401 self ._device_info = await self .waterHeater .get_status ()
402+ LOGGER .debug ("Rinnai device data: %s" , self ._device_info )
403+
404+ def start_maintenance_timer (self ):
405+ """Start the maintenance retrieval timer if enabled.
406+
407+ Note: The first maintenance retrieval will occur after the configured interval,
408+ not immediately. This prevents unnecessary API calls during initialization.
409+ """
410+ # Cancel any existing timers first
411+ if self ._unsub_maintenance_delay :
412+ self ._unsub_maintenance_delay ()
413+ self ._unsub_maintenance_delay = None
414+ if self ._unsub_maintenance_timer :
415+ self ._unsub_maintenance_timer ()
416+ self ._unsub_maintenance_timer = None
400417
401- # Handle dynamic maintenance update interval
402- if self .options [CONF_MAINT_INTERVAL_ENABLED ]:
403- # Cancel previous maintenance update timer if it exists
404- if self ._unsub_maintenance_timer :
405- self ._unsub_maintenance_timer ()
418+ # Only set up timer if maintenance is enabled
419+ if self .options .get (CONF_MAINT_INTERVAL_ENABLED , False ):
420+ from datetime import datetime
421+ next_run = datetime .now () + self .maint_refresh_interval
422+ LOGGER .info (
423+ "Maintenance retrieval scheduled. First run will occur at approximately %s (in %s seconds)" ,
424+ next_run .strftime ("%H:%M:%S" ),
425+ self .maint_refresh_interval .total_seconds (),
426+ )
406427
407- # Set new maintenance update interval
408- self ._unsub_maintenance_timer = async_track_time_interval (
409- self .hass , self .async_do_maintenance_retrieval , self .maint_refresh_interval
428+ # Schedule the first call after the interval delay
429+ # This prevents immediate execution on startup
430+ self ._unsub_maintenance_delay = async_call_later (
431+ self .hass ,
432+ self .maint_refresh_interval .total_seconds (),
433+ self ._start_maintenance_interval ,
410434 )
411435 else :
412- LOGGER .debug ("Skipping Maintenance retrieval since disabled inside of configuration" )
436+ LOGGER .debug ("Maintenance retrieval disabled in configuration" )
437+
438+ @callback
439+ def _start_maintenance_interval (self , _now = None ):
440+ """Start the recurring maintenance interval timer.
413441
414- LOGGER .debug ("Rinnai device data: %s" , self ._device_info )
415-
416- async def async_added_to_hass (self ):
417- """Called when the device is added to Home Assistant"""
418- # If maintenance retrieval is enabled, initialize the timer
419- if self .options [CONF_MAINT_INTERVAL_ENABLED ]:
420- self ._unsub_maintenance_timer = async_track_time_interval (
421- self .hass , self .async_do_maintenance_retrieval , self .maint_refresh_interval
422- )
423-
424- async def async_will_remove_from_hass (self ):
425- """Called when the device is removed from Home Assistant"""
426- # Unsubscribe from any existing maintenance update timer
442+ This is called after the initial delay to set up the recurring timer.
443+ """
444+ # Clear the delay timer reference since it's now complete
445+ self ._unsub_maintenance_delay = None
446+
447+ LOGGER .info (
448+ "Starting maintenance retrieval cycle. Will run every %s" ,
449+ self .maint_refresh_interval ,
450+ )
451+
452+ # Perform the first maintenance retrieval
453+ self .hass .async_create_task (self .async_do_maintenance_retrieval ())
454+
455+ # Set up recurring timer for subsequent calls
456+ self ._unsub_maintenance_timer = async_track_time_interval (
457+ self .hass , self .async_do_maintenance_retrieval , self .maint_refresh_interval
458+ )
459+
460+ def stop_maintenance_timer (self ):
461+ """Stop the maintenance retrieval timer and any pending delayed calls"""
462+ # Cancel the delayed initial call if it hasn't fired yet
463+ if self ._unsub_maintenance_delay :
464+ self ._unsub_maintenance_delay ()
465+ self ._unsub_maintenance_delay = None
466+ LOGGER .debug ("Cancelled pending maintenance retrieval delay" )
467+
468+ # Cancel the recurring timer if it exists
427469 if self ._unsub_maintenance_timer :
428470 self ._unsub_maintenance_timer ()
429- self ._unsub_maintenance_timer = None
471+ self ._unsub_maintenance_timer = None
472+ LOGGER .debug ("Maintenance retrieval timer stopped" )
473+
474+ async def async_shutdown (self ):
475+ """Called when the coordinator is being shut down"""
476+ # Clean up the maintenance timer
477+ self .stop_maintenance_timer ()
0 commit comments