@@ -61,6 +61,7 @@ class PyADTPulseAsync:
61
61
"_site" ,
62
62
"_detailed_debug_logging" ,
63
63
"_sync_check_exception" ,
64
+ "_sync_check_sleeping" ,
64
65
)
65
66
66
67
@typechecked
@@ -129,6 +130,7 @@ def __init__(
129
130
pc_backoff = self ._pulse_connection .get_login_backoff ()
130
131
self ._sync_check_exception : Exception | None = PulseNotLoggedInError ()
131
132
pc_backoff .reset_backoff ()
133
+ self ._sync_check_sleeping = asyncio .Event ()
132
134
133
135
def __repr__ (self ) -> str :
134
136
"""Object representation."""
@@ -138,12 +140,21 @@ def __repr__(self) -> str:
138
140
139
141
async def _update_sites (self , soup : BeautifulSoup ) -> None :
140
142
with self ._pa_attribute_lock :
143
+ start_time = 0.0
144
+ if self ._pulse_connection .detailed_debug_logging :
145
+ start_time = time .time ()
141
146
if self ._site is None :
142
147
await self ._initialize_sites (soup )
143
148
if self ._site is None :
144
149
raise RuntimeError ("pyadtpulse could not retrieve site" )
145
150
self ._site .alarm_control_panel .update_alarm_from_soup (soup )
146
151
self ._site .update_zone_from_soup (soup )
152
+ if self ._pulse_connection .detailed_debug_logging :
153
+ LOG .debug (
154
+ "Updated site %s in %s seconds" ,
155
+ self ._site .id ,
156
+ time .time () - start_time ,
157
+ )
147
158
148
159
async def _initialize_sites (self , soup : BeautifulSoup ) -> None :
149
160
"""
@@ -159,7 +170,9 @@ async def _initialize_sites(self, soup: BeautifulSoup) -> None:
159
170
single_premise = soup .find ("span" , {"id" : "p_singlePremise" })
160
171
if single_premise :
161
172
site_name = single_premise .text
162
-
173
+ start_time = 0.0
174
+ if self ._pulse_connection .detailed_debug_logging :
175
+ start_time = time .time ()
163
176
# FIXME: this code works, but it doesn't pass the linter
164
177
signout_link = str (
165
178
soup .find ("a" , {"class" : "p_signoutlink" }).get ("href" ) # type: ignore
@@ -180,6 +193,12 @@ async def _initialize_sites(self, soup: BeautifulSoup) -> None:
180
193
new_site .gateway .is_online = False
181
194
new_site .update_zone_from_soup (soup )
182
195
self ._site = new_site
196
+ if self ._pulse_connection .detailed_debug_logging :
197
+ LOG .debug (
198
+ "Initialized site %s in %s seconds" ,
199
+ self ._site .id ,
200
+ time .time () - start_time ,
201
+ )
183
202
return
184
203
else :
185
204
LOG .warning (
@@ -241,6 +260,7 @@ def should_relogin(relogin_interval: int) -> bool:
241
260
> randint (int (0.75 * relogin_interval ), relogin_interval )
242
261
)
243
262
263
+ next_full_logout_time = time .time () + 24 * 60 * 60
244
264
response : str | None
245
265
task_name : str = self ._get_task_name (self ._timeout_task , KEEPALIVE_TASK_NAME )
246
266
LOG .debug ("creating %s" , task_name )
@@ -257,8 +277,24 @@ def should_relogin(relogin_interval: int) -> bool:
257
277
if not self ._pulse_connection .is_connected :
258
278
LOG .debug ("%s: Skipping relogin because not connected" , task_name )
259
279
continue
260
- elif should_relogin (relogin_interval ):
261
- await self ._pulse_connection .quick_logout ()
280
+ if should_relogin (relogin_interval ):
281
+ msg = "quick"
282
+ if time .time () > next_full_logout_time :
283
+ msg = "full"
284
+ with self ._pa_attribute_lock :
285
+ if self ._sync_task :
286
+ if self ._detailed_debug_logging :
287
+ LOG .debug (
288
+ "%s: waiting for sync check task to sleep" ,
289
+ task_name ,
290
+ )
291
+ await self ._sync_check_sleeping .wait ()
292
+ if msg == "full" :
293
+ next_full_logout_time = time .time () + 24 * 60 * 60
294
+ await self .async_logout ()
295
+ else :
296
+ await self ._pulse_connection .quick_logout ()
297
+ LOG .debug ("%s: performing %s logout" , task_name , msg )
262
298
try :
263
299
await self ._login_looped (task_name )
264
300
except (PulseAuthenticationError , PulseMFARequiredError ) as ex :
@@ -458,14 +494,15 @@ async def shutdown_task(ex: Exception):
458
494
459
495
while True :
460
496
try :
497
+ self ._sync_check_sleeping .set ()
461
498
if not have_updates and not self .site .gateway .is_online :
462
499
# gateway going back online will trigger a sync check of 1-0-0
463
500
await self .site .gateway .backoff .wait_for_backoff ()
464
501
else :
465
502
await asyncio .sleep (
466
503
self .site .gateway .poll_interval if not have_updates else 0.0
467
504
)
468
-
505
+ self . _sync_check_sleeping . clear ()
469
506
try :
470
507
code , response_text , url = await perform_sync_check_query ()
471
508
except (
0 commit comments