2424from appdaemon .models .config .app import AppConfig
2525from appdaemon .parse import resolve_time_str
2626from appdaemon .state import StateCallbackType
27+ from .types import TimeDeltaLike
2728
2829T = TypeVar ("T" )
2930
@@ -1413,9 +1414,9 @@ async def listen_state(
14131414 namespace : str | None = None ,
14141415 new : str | Callable [[Any ], bool ] | None = None ,
14151416 old : str | Callable [[Any ], bool ] | None = None ,
1416- duration : str | int | float | timedelta | None = None ,
1417+ duration : TimeDeltaLike | None = None ,
14171418 attribute : str | None = None ,
1418- timeout : str | int | float | timedelta | None = None ,
1419+ timeout : TimeDeltaLike | None = None ,
14191420 immediate : bool = False ,
14201421 oneshot : bool = False ,
14211422 pin : bool | None = None ,
@@ -1432,9 +1433,9 @@ async def listen_state(
14321433 namespace : str | None = None ,
14331434 new : str | Callable [[Any ], bool ] | None = None ,
14341435 old : str | Callable [[Any ], bool ] | None = None ,
1435- duration : str | int | float | timedelta | None = None ,
1436+ duration : TimeDeltaLike | None = None ,
14361437 attribute : str | None = None ,
1437- timeout : str | int | float | timedelta | None = None ,
1438+ timeout : TimeDeltaLike | None = None ,
14381439 immediate : bool = False ,
14391440 oneshot : bool = False ,
14401441 pin : bool | None = None ,
@@ -1450,9 +1451,9 @@ async def listen_state(
14501451 namespace : str | None = None ,
14511452 new : str | Callable [[Any ], bool ] | None = None ,
14521453 old : str | Callable [[Any ], bool ] | None = None ,
1453- duration : str | int | float | timedelta | None = None ,
1454+ duration : TimeDeltaLike | None = None ,
14541455 attribute : str | None = None ,
1455- timeout : str | int | float | timedelta | None = None ,
1456+ timeout : TimeDeltaLike | None = None ,
14561457 immediate : bool = False ,
14571458 oneshot : bool = False ,
14581459 pin : bool | None = None ,
@@ -1486,7 +1487,7 @@ async def listen_state(
14861487 careful when comparing them. The ``self.get_state()`` method is useful for checking the data type of
14871488 the desired attribute. If ``old`` is a callable (lambda, function, etc), then it will be called with
14881489 the old state, and the callback will only be invoked if the callable returns ``True``.
1489- duration (str | int | float | timedelta , optional): If supplied, the callback will not be invoked unless the
1490+ duration (TimeDeltaLike , optional): If supplied, the callback will not be invoked unless the
14901491 desired state is maintained for that amount of time. This requires that a specific attribute is
14911492 specified (or the default of ``state`` is used), and should be used in conjunction with either or both
14921493 of the ``new`` and ``old`` parameters. When the callback is called, it is supplied with the values of
@@ -1500,7 +1501,7 @@ async def listen_state(
15001501 the default behavior is to use the value of ``state``. Using the value ``all`` will cause the callback
15011502 to get triggered for any change in state, and the new/old values used for the callback will be the
15021503 entire state dict rather than the individual value of an attribute.
1503- timeout (str | int | float | timedelta , optional): If given, the callback will be automatically removed
1504+ timeout (TimeDeltaLike , optional): If given, the callback will be automatically removed
15041505 after that amount of time. If activity for the listened state has occurred that would trigger a
15051506 duration timer, the duration timer will still be fired even though the callback has been removed.
15061507 immediate (bool, optional): If given, it enables the countdown for a delay parameter to start at the time.
@@ -2102,7 +2103,7 @@ async def listen_event(
21022103 event : str | None = None ,
21032104 * ,
21042105 namespace : str | None = None ,
2105- timeout : str | int | float | timedelta | None = None ,
2106+ timeout : TimeDeltaLike | None = None ,
21062107 oneshot : bool = False ,
21072108 pin : bool | None = None ,
21082109 pin_thread : int | None = None ,
@@ -2117,7 +2118,7 @@ async def listen_event(
21172118 event : list [str ],
21182119 * ,
21192120 namespace : str | None = None ,
2120- timeout : str | int | float | timedelta | None = None ,
2121+ timeout : TimeDeltaLike | None = None ,
21212122 oneshot : bool = False ,
21222123 pin : bool | None = None ,
21232124 pin_thread : int | None = None ,
@@ -2131,7 +2132,7 @@ async def listen_event(
21312132 event : str | Iterable [str ] | None = None ,
21322133 * , # Arguments after this are keyword only
21332134 namespace : str | Literal ["global" ] | None = None ,
2134- timeout : str | int | float | timedelta | None = None ,
2135+ timeout : TimeDeltaLike | None = None ,
21352136 oneshot : bool = False ,
21362137 pin : bool | None = None ,
21372138 pin_thread : int | None = None ,
@@ -2294,7 +2295,7 @@ async def fire_event(
22942295 self ,
22952296 event : str ,
22962297 namespace : str | None = None ,
2297- timeout : str | int | float | timedelta | None = - 1 , # Used by utils.sync_decorator
2298+ timeout : TimeDeltaLike | None = - 1 , # Used by utils.sync_decorator
22982299 ** kwargs ,
22992300 ) -> None :
23002301 """Fires an event on the AppDaemon bus, for apps and plugins.
@@ -2747,7 +2748,7 @@ async def reset_timer(self, handle: str) -> bool:
27472748 return await self .AD .sched .reset_timer (self .name , handle )
27482749
27492750 @utils .sync_decorator
2750- async def info_timer (self , handle : str ) -> tuple [dt .datetime , int , dict ] | None :
2751+ async def info_timer (self , handle : str ) -> tuple [dt .datetime , float , dict ] | None :
27512752 """Get information about a previously created timer.
27522753
27532754 Args:
@@ -2757,24 +2758,27 @@ async def info_timer(self, handle: str) -> tuple[dt.datetime, int, dict] | None:
27572758 A tuple with the following values or ``None`` if handle is invalid or timer no longer exists.
27582759
27592760 - `time` - datetime object representing the next time the callback will be fired
2760- - `interval` - repeat interval if applicable, `0` otherwise.
2761+ - `interval` - repeat interval in seconds if applicable, `0` otherwise.
27612762 - `kwargs` - the values supplied when the callback was initially created.
27622763
27632764 Examples:
27642765 >>> if (info := self.info_timer(handle)) is not None:
27652766 >>> time, interval, kwargs = info
27662767
27672768 """
2768- return await self .AD .sched .info_timer (handle , self .name )
2769+ if (result := await self .AD .sched .info_timer (handle , self .name )) is not None :
2770+ time , interval , kwargs = result
2771+ return time , interval .total_seconds (), kwargs
2772+ return None
27692773
27702774 @utils .sync_decorator
27712775 async def run_in (
27722776 self ,
27732777 callback : Callable ,
2774- delay : str | int | float | timedelta ,
2778+ delay : TimeDeltaLike ,
27752779 * args ,
2776- random_start : int | None = None ,
2777- random_end : int | None = None ,
2780+ random_start : TimeDeltaLike | None = None ,
2781+ random_end : TimeDeltaLike | None = None ,
27782782 pin : bool | None = None ,
27792783 pin_thread : int | None = None ,
27802784 ** kwargs ,
@@ -2826,8 +2830,8 @@ async def run_in(
28262830 name = self .name ,
28272831 aware_dt = exec_time ,
28282832 callback = sched_func ,
2829- random_start = random_start ,
2830- random_end = random_end ,
2833+ random_start = utils . parse_timedelta_or_none ( random_start ) ,
2834+ random_end = utils . parse_timedelta_or_none ( random_end ) ,
28312835 pin = pin ,
28322836 pin_thread = pin_thread ,
28332837 )
@@ -2838,8 +2842,8 @@ async def run_once(
28382842 callback : Callable ,
28392843 start : str | dt .time | dt .datetime | None = None ,
28402844 * args ,
2841- random_start : int | None = None ,
2842- random_end : int | None = None ,
2845+ random_start : TimeDeltaLike | None = None ,
2846+ random_end : TimeDeltaLike | None = None ,
28432847 pin : bool | None = None ,
28442848 pin_thread : int | None = None ,
28452849 ** kwargs ,
@@ -2908,8 +2912,8 @@ async def run_at(
29082912 callback : Callable ,
29092913 start : str | dt .time | dt .datetime ,
29102914 * args ,
2911- random_start : int | None = None ,
2912- random_end : int | None = None ,
2915+ random_start : TimeDeltaLike | None = None ,
2916+ random_end : TimeDeltaLike | None = None ,
29132917 pin : bool | None = None ,
29142918 pin_thread : int | None = None ,
29152919 ** kwargs ,
@@ -2962,6 +2966,9 @@ async def run_at(
29622966
29632967 """
29642968 start = "now" if start is None else start
2969+ random_start_td = utils .parse_timedelta_or_none (random_start )
2970+ random_end_td = utils .parse_timedelta_or_none (random_end )
2971+
29652972 match start :
29662973 case str () as start_str if start .startswith ("sun" ):
29672974 if start .startswith ("sunrise" ):
@@ -2982,14 +2989,14 @@ async def run_at(
29822989 self .AD .sched .insert_schedule ,
29832990 name = self .name ,
29842991 aware_dt = start ,
2985- interval = timedelta (days = 1 ). total_seconds ()
2992+ interval = timedelta (days = 1 )
29862993 ) # fmt: skip
29872994
29882995 func = functools .partial (
29892996 func ,
29902997 callback = functools .partial (callback , * args , ** kwargs ),
2991- random_start = random_start ,
2992- random_end = random_end ,
2998+ random_start = random_start_td ,
2999+ random_end = random_end_td ,
29933000 pin = pin ,
29943001 pin_thread = pin_thread ,
29953002 )
@@ -3001,8 +3008,8 @@ async def run_daily(
30013008 callback : Callable ,
30023009 start : str | dt .time | dt .datetime | None = None ,
30033010 * args ,
3004- random_start : int | None = None ,
3005- random_end : int | None = None ,
3011+ random_start : TimeDeltaLike | None = None ,
3012+ random_end : TimeDeltaLike | None = None ,
30063013 pin : bool | None = None ,
30073014 pin_thread : int | None = None ,
30083015 ** kwargs ,
@@ -3094,8 +3101,8 @@ async def run_hourly(
30943101 callback : Callable ,
30953102 start : str | dt .time | dt .datetime | None = None ,
30963103 * args ,
3097- random_start : int | None = None ,
3098- random_end : int | None = None ,
3104+ random_start : TimeDeltaLike | None = None ,
3105+ random_end : TimeDeltaLike | None = None ,
30993106 pin : bool | None = None ,
31003107 pin_thread : int | None = None ,
31013108 ** kwargs ,
@@ -3155,8 +3162,8 @@ async def run_minutely(
31553162 callback : Callable ,
31563163 start : str | dt .time | dt .datetime | None = None ,
31573164 * args ,
3158- random_start : int | None = None ,
3159- random_end : int | None = None ,
3165+ random_start : TimeDeltaLike | None = None ,
3166+ random_end : TimeDeltaLike | None = None ,
31603167 pin : bool | None = None ,
31613168 pin_thread : int | None = None ,
31623169 ** kwargs ,
@@ -3216,10 +3223,10 @@ async def run_every(
32163223 self ,
32173224 callback : Callable ,
32183225 start : str | dt .time | dt .datetime | None = None ,
3219- interval : str | int | float | timedelta = 0 ,
3226+ interval : TimeDeltaLike = 0 ,
32203227 * args ,
3221- random_start : int | None = None ,
3222- random_end : int | None = None ,
3228+ random_start : TimeDeltaLike | None = None ,
3229+ random_end : TimeDeltaLike | None = None ,
32233230 pin : bool | None = None ,
32243231 pin_thread : int | None = None ,
32253232 ** kwargs ,
@@ -3317,9 +3324,9 @@ def timed_callback(self, **kwargs): ... # example callback
33173324 aware_dt = next_period ,
33183325 callback = functools .partial (callback , * args , ** kwargs ),
33193326 repeat = True ,
3320- interval = interval . total_seconds () ,
3321- random_start = random_start ,
3322- random_end = random_end ,
3327+ interval = interval ,
3328+ random_start = utils . parse_timedelta_or_none ( random_start ) ,
3329+ random_end = utils . parse_timedelta_or_none ( random_end ) ,
33233330 pin = pin ,
33243331 pin_thread = pin_thread ,
33253332 )
@@ -3330,9 +3337,9 @@ async def run_at_sunset(
33303337 callback : Callable ,
33313338 * args ,
33323339 repeat : bool = True ,
3333- offset : str | int | float | timedelta | None = None ,
3334- random_start : int | None = None ,
3335- random_end : int | None = None ,
3340+ offset : TimeDeltaLike | None = None ,
3341+ random_start : TimeDeltaLike | None = None ,
3342+ random_end : TimeDeltaLike | None = None ,
33363343 pin : bool | None = None ,
33373344 pin_thread : int | None = None ,
33383345 ** kwargs ,
@@ -3383,20 +3390,20 @@ async def run_at_sunset(
33833390 """
33843391 now = await self .AD .sched .get_now ()
33853392 sunset = await self .AD .sched .todays_sunset ()
3386- td = utils .parse_timedelta (offset )
3387- if sunset + td < now :
3393+ offset_td = utils .parse_timedelta (offset )
3394+ if sunset + offset_td < now :
33883395 sunset = await self .AD .sched .next_sunset ()
33893396
3390- self .logger .debug (f"Registering run_at_sunset at { sunset + td } with { args } , { kwargs } " )
3397+ self .logger .debug (f"Registering run_at_sunset at { sunset + offset_td } with { args } , { kwargs } " )
33913398 return await self .AD .sched .insert_schedule (
33923399 name = self .name ,
33933400 aware_dt = sunset ,
33943401 callback = functools .partial (callback , * args , ** kwargs ),
33953402 repeat = repeat ,
33963403 type_ = "next_setting" ,
3397- offset = offset ,
3398- random_start = random_start ,
3399- random_end = random_end ,
3404+ offset = offset_td ,
3405+ random_start = utils . parse_timedelta_or_none ( random_start ) ,
3406+ random_end = utils . parse_timedelta_or_none ( random_end ) ,
34003407 pin = pin ,
34013408 pin_thread = pin_thread ,
34023409 )
@@ -3407,9 +3414,9 @@ async def run_at_sunrise(
34073414 callback : Callable ,
34083415 * args ,
34093416 repeat : bool = True ,
3410- offset : str | int | float | timedelta | None = None ,
3411- random_start : int | None = None ,
3412- random_end : int | None = None ,
3417+ offset : TimeDeltaLike | None = None ,
3418+ random_start : TimeDeltaLike | None = None ,
3419+ random_end : TimeDeltaLike | None = None ,
34133420 pin : bool | None = None ,
34143421 pin_thread : int | None = None ,
34153422 ** kwargs ,
@@ -3460,19 +3467,19 @@ async def run_at_sunrise(
34603467 """
34613468 now = await self .AD .sched .get_now ()
34623469 sunrise = await self .AD .sched .todays_sunrise ()
3463- td = utils .parse_timedelta (offset )
3464- if sunrise + td < now :
3470+ offset_td = utils .parse_timedelta (offset )
3471+ if sunrise + offset_td < now :
34653472 sunrise = await self .AD .sched .next_sunrise ()
3466- self .logger .debug (f"Registering run_at_sunrise at { sunrise + td } with { args } , { kwargs } " )
3473+ self .logger .debug (f"Registering run_at_sunrise at { sunrise + offset_td } with { args } , { kwargs } " )
34673474 return await self .AD .sched .insert_schedule (
34683475 name = self .name ,
34693476 aware_dt = sunrise ,
34703477 callback = functools .partial (callback , * args , ** kwargs ),
34713478 repeat = repeat ,
34723479 type_ = "next_rising" ,
3473- offset = offset ,
3474- random_start = random_start ,
3475- random_end = random_end ,
3480+ offset = offset_td ,
3481+ random_start = utils . parse_timedelta_or_none ( random_start ) ,
3482+ random_end = utils . parse_timedelta_or_none ( random_end ) ,
34763483 pin = pin ,
34773484 pin_thread = pin_thread ,
34783485 )
@@ -3484,7 +3491,7 @@ async def run_at_sunrise(
34843491 def dash_navigate (
34853492 self ,
34863493 target : str ,
3487- timeout : str | int | float | timedelta | None = - 1 , # Used by utils.sync_decorator
3494+ timeout : TimeDeltaLike | None = - 1 , # Used by utils.sync_decorator
34883495 ret : str | None = None ,
34893496 sticky : int = 0 ,
34903497 deviceid : str | None = None ,
0 commit comments