@@ -78,7 +78,7 @@ class StreamDeck(ABC):
7878 DECK_VISUAL = False
7979 DECK_TOUCH = False
8080
81- def __init__ (self , device ):
81+ def __init__ (self , device , resume_from_suspend : bool = True ):
8282 self .device = device
8383 self .last_key_states = [False ] * (self .KEY_COUNT + self .TOUCH_KEY_COUNT )
8484 self .last_dial_states = [False ] * self .DIAL_COUNT
@@ -200,6 +200,63 @@ def _read(self):
200200 self .run_read_thread = False
201201 self .close ()
202202
203+ def _read_with_resume_from_suspend (self ):
204+ """
205+ Read handler for the underlying transport, listening for button state
206+ changes on the underlying device, caching the new states and firing off
207+ any registered callbacks.
208+ """
209+ while self .run_read_thread :
210+ try :
211+ control_states = self ._read_control_states ()
212+ if control_states is None :
213+ time .sleep (1.0 / self .read_poll_hz )
214+ continue
215+
216+ if ControlType .KEY in control_states and self .key_callback is not None :
217+ for k , (old , new ) in enumerate (zip (self .last_key_states , control_states [ControlType .KEY ])):
218+ if old != new :
219+ self .last_key_states [k ] = new
220+ self .key_callback (self , k , new )
221+
222+ elif ControlType .DIAL in control_states and self .dial_callback is not None :
223+ if DialEventType .PUSH in control_states [ControlType .DIAL ]:
224+ for k , (old , new ) in enumerate (zip (self .last_dial_states ,
225+ control_states [ControlType .DIAL ][DialEventType .PUSH ])):
226+ if old != new :
227+ self .last_dial_states [k ] = new
228+ self .dial_callback (self , k , DialEventType .PUSH , new )
229+
230+ if DialEventType .TURN in control_states [ControlType .DIAL ]:
231+ for k , amount in enumerate (control_states [ControlType .DIAL ][DialEventType .TURN ]):
232+ if amount != 0 :
233+ self .dial_callback (self , k , DialEventType .TURN , amount )
234+
235+ elif ControlType .TOUCHSCREEN in control_states and self .touchscreen_callback is not None :
236+ self .touchscreen_callback (self , * control_states [ControlType .TOUCHSCREEN ])
237+
238+ except TransportError :
239+ self .run_read_thread = False
240+ self .close ()
241+
242+ if self .reconnect_after_suspend :
243+ if self .connected () and not self .is_open ():
244+ # This is the case when resuming from suspend
245+ TIMEOUT = 10
246+ start_time = time .time ()
247+ while True :
248+ try :
249+ self .open ()
250+ break
251+ except TransportError :
252+ time .sleep (0.1 )
253+
254+ if not self .connected ():
255+ break
256+
257+ if time .time () - start_time > TIMEOUT :
258+ break
259+
203260 def _setup_reader (self , callback ):
204261 """
205262 Sets up the internal transport reader thread with the given callback,
@@ -233,7 +290,10 @@ def open(self):
233290 self .device .open ()
234291
235292 self ._reset_key_stream ()
236- self ._setup_reader (self ._read )
293+ if self .resume_from_suspend :
294+ self ._setup_reader (self ._read_with_resume_from_suspend )
295+ else :
296+ self ._setup_reader (self ._read )
237297
238298 def close (self ):
239299 """
0 commit comments