@@ -136,15 +136,15 @@ def init(cls, hass):
136136 cls .hass = hass
137137
138138 def wait_until_factory (ast_ctx ):
139- """Return wapper to call to astFunction with the ast context."""
139+ """Return wrapper to call to astFunction with the ast context."""
140140
141141 async def wait_until_call (* arg , ** kw ):
142142 return await cls .wait_until (ast_ctx , * arg , ** kw )
143143
144144 return wait_until_call
145145
146146 def user_task_create_factory (ast_ctx ):
147- """Return wapper to call to astFunction with the ast context."""
147+ """Return wrapper to call to astFunction with the ast context."""
148148
149149 async def user_task_create (func , * args , ** kwargs ):
150150 """Implement task.create()."""
@@ -610,6 +610,7 @@ async def parse_date_time(cls, date_time_str, day_offset, now, startup_time):
610610 year = now .year
611611 month = now .month
612612 day = now .day
613+ fixed_date = False
613614
614615 dt_str_orig = dt_str = date_time_str .strip ().lower ()
615616 #
@@ -623,6 +624,7 @@ async def parse_date_time(cls, date_time_str, day_offset, now, startup_time):
623624 else :
624625 month , day = int (match0 [1 ]), int (match0 [2 ])
625626 day_offset = 0 # explicit date means no offset
627+ fixed_date = True
626628 dt_str = dt_str [len (match0 .group (0 )) :]
627629 elif match1 :
628630 skip = True
@@ -632,11 +634,17 @@ async def parse_date_time(cls, date_time_str, day_offset, now, startup_time):
632634 day_offset = dow - (now .isoweekday () % 7 )
633635 else :
634636 day_offset = 7 + dow - (now .isoweekday () % 7 )
637+ fixed_date = True
635638 elif match1 [1 ] == "today" :
636639 day_offset = 0
640+ fixed_date = True
637641 elif match1 [1 ] == "tomorrow" :
638642 day_offset = 1
643+ fixed_date = True
639644 else :
645+ if match1 [1 ] == "now" :
646+ day_offset = 0
647+ fixed_date = True
640648 skip = False
641649 if skip :
642650 dt_str = dt_str [len (match1 .group (0 )) :]
@@ -649,7 +657,7 @@ async def parse_date_time(cls, date_time_str, day_offset, now, startup_time):
649657 now = dt .datetime (year , month , day )
650658 dt_str = dt_str .strip ()
651659 if len (dt_str ) == 0 :
652- return now
660+ return now , fixed_date
653661
654662 #
655663 # parse the time
@@ -682,7 +690,7 @@ async def parse_date_time(cls, date_time_str, day_offset, now, startup_time):
682690 except Exception :
683691 _LOGGER .warning ("'%s' not defined at this latitude" , dt_str )
684692 # return something in the past so it is ignored
685- return now - dt .timedelta (days = 100 )
693+ return now - dt .timedelta (days = 100 ), fixed_date
686694 now += time_sun .date () - now .date ()
687695 hour , mins , sec = time_sun .hour , time_sun .minute , time_sun .second
688696 elif dt_str .startswith ("noon" ):
@@ -707,7 +715,7 @@ async def parse_date_time(cls, date_time_str, day_offset, now, startup_time):
707715 dt_str = dt_str .strip ()
708716 if len (dt_str ) > 0 :
709717 now = now + dt .timedelta (seconds = parse_time_offset (dt_str ))
710- return now
718+ return now , fixed_date
711719
712720 @classmethod
713721 async def timer_active_check (cls , time_spec , now , startup_time ):
@@ -737,8 +745,8 @@ async def timer_active_check(cls, time_spec, now, startup_time):
737745 _LOGGER .error ("Invalid range expression: %s" , exc )
738746 return False
739747
740- start = await cls .parse_date_time (dt_start .strip (), 0 , now , startup_time )
741- end = await cls .parse_date_time (dt_end .strip (), 0 , start , startup_time )
748+ start , _ = await cls .parse_date_time (dt_start .strip (), 0 , now , startup_time )
749+ end , _ = await cls .parse_date_time (dt_end .strip (), 0 , start , startup_time )
742750
743751 if start <= end :
744752 this_match = start <= now <= end
@@ -802,20 +810,20 @@ async def timer_trigger_next(cls, time_spec, now, startup_time):
802810 next_time_adj = now + delta
803811
804812 elif len (match1 ) == 3 :
805- this_t = await cls .parse_date_time (match1 [1 ].strip (), 0 , now , startup_time )
813+ this_t , _ = await cls .parse_date_time (match1 [1 ].strip (), 0 , now , startup_time )
806814 day_offset = (now - this_t ).days + 1
807815 if day_offset != 0 and this_t != startup_time :
808816 #
809817 # Try a day offset (won't make a difference if spec has full date)
810818 #
811- this_t = await cls .parse_date_time (match1 [1 ].strip (), day_offset , now , startup_time )
819+ this_t , _ = await cls .parse_date_time (match1 [1 ].strip (), day_offset , now , startup_time )
812820 startup = now == this_t and now == startup_time
813821 if (now < this_t or startup ) and (next_time is None or this_t < next_time ):
814822 next_time_adj = next_time = this_t
815823
816824 elif len (match2 ) == 5 :
817825 start_str , period_str = match2 [1 ].strip (), match2 [2 ].strip ()
818- start = await cls .parse_date_time (start_str , 0 , now , startup_time )
826+ start , fixed_date_start = await cls .parse_date_time (start_str , 0 , now , startup_time )
819827 period = parse_time_offset (period_str )
820828 if period <= 0 :
821829 _LOGGER .error ("Invalid non-positive period %s in period(): %s" , period , time_spec )
@@ -832,12 +840,17 @@ async def timer_trigger_next(cls, time_spec, now, startup_time):
832840 next_time_adj = next_time = this_t
833841 continue
834842 end_str = match2 [3 ].strip ()
835- end = await cls .parse_date_time (end_str , 0 , now , startup_time )
836- end_offset = 1 if end < start else 0
837- for day in [- 1 , 0 , 1 ]:
838- start = await cls .parse_date_time (start_str , day , now , startup_time )
839- end = await cls .parse_date_time (end_str , day + end_offset , now , startup_time )
840- if now < start or (now == start and now == startup_time ):
843+ end , fixed_date_end = await cls .parse_date_time (end_str , 0 , now , startup_time )
844+ if not fixed_date_start and not fixed_date_end :
845+ end_offset = 1 if end < start else 0
846+ day_dither = [- 1 , 0 , 1 ]
847+ else :
848+ end_offset = 0
849+ day_dither = [0 ]
850+ for day in day_dither :
851+ start , _ = await cls .parse_date_time (start_str , day , now , startup_time )
852+ end , _ = await cls .parse_date_time (end_str , day + end_offset , now , startup_time )
853+ if (now < start or (now == start and now == startup_time )) and start <= end :
841854 if next_time is None or start < next_time :
842855 next_time_adj = next_time = start
843856 break
0 commit comments