44"""
55import logging
66import time
7+ from collections .abc import Sequence
78from datetime import datetime
89from datetime import timezone
10+ from typing import Any
11+ from typing import ClassVar
12+ from typing import cast
913
14+ from bleak import BleakClient
1015from cubing_algs .facelets import cubies_to_facelets
1116
1217from term_timer .bluetooth .constants import DEBOUNCE
1520from term_timer .bluetooth .constants import GAN_GEN3_STATE_CHARACTERISTIC
1621from term_timer .bluetooth .drivers .gan_gen2 import GanGen2Driver
1722from term_timer .bluetooth .message import GanProtocolMessage
23+ from term_timer .bluetooth .types import EventDict
24+ from term_timer .bluetooth .types import MoveEventDict
1825
1926logger = logging .getLogger (__name__ )
2027
@@ -23,19 +30,19 @@ class GanGen3Driver(GanGen2Driver):
2330 """
2431 GAN356 i Carry 2
2532 """
26- service_uid = GAN_GEN3_SERVICE
27- state_characteristic_uid = GAN_GEN3_STATE_CHARACTERISTIC
28- command_characteristic_uid = GAN_GEN3_COMMAND_CHARACTERISTIC
33+ service_uid : ClassVar [ str ] = GAN_GEN3_SERVICE
34+ state_characteristic_uid : ClassVar [ str ] = GAN_GEN3_STATE_CHARACTERISTIC
35+ command_characteristic_uid : ClassVar [ str ] = GAN_GEN3_COMMAND_CHARACTERISTIC
2936
30- def __init__ (self , client ) :
37+ def __init__ (self , client : BleakClient ) -> None :
3138 super ().__init__ (client )
3239
33- self .serial = - 1
34- self .last_serial = - 1
35- self .last_local_timestamp = None
36- self .move_buffer = []
40+ self .serial : int = - 1
41+ self .last_serial : int = - 1
42+ self .last_local_timestamp : datetime | None = None
43+ self .move_buffer : list [ MoveEventDict ] = []
3744
38- def send_command_handler (self , command : str ):
45+ def send_command_handler (self , command : str ) -> bytes | bool :
3946 msg = bytearray (16 )
4047
4148 if command == 'REQUEST_FACELETS' :
@@ -58,7 +65,7 @@ def send_command_handler(self, command: str):
5865
5966 return self .cypher .encrypt (bytes (msg ))
6067
61- async def request_move_history (self , serial , count ) :
68+ async def request_move_history (self , serial : int , count : int ) -> None :
6269 msg = bytearray (16 )
6370
6471 # Move history response data is byte-aligned,
@@ -89,8 +96,8 @@ async def request_move_history(self, serial, count):
8996 self .cypher .encrypt (bytes (msg )),
9097 )
9198
92- async def evict_move_buffer (self ):
93- evicted_events = []
99+ async def evict_move_buffer (self ) -> list [ MoveEventDict ] :
100+ evicted_events : list [ MoveEventDict ] = []
94101
95102 while len (self .move_buffer ) > 0 :
96103 buffer_head = self .move_buffer [0 ]
@@ -104,19 +111,20 @@ async def evict_move_buffer(self):
104111 self .last_serial = buffer_head ['serial' ]
105112
106113 if len (self .move_buffer ) > 16 :
107- self .client .disconnect ()
114+ await self .client .disconnect ()
108115
109116 return evicted_events
110117
111- def is_serial_in_range (self , start , end , serial ,
112- * , closed_start = False , closed_end = False ):
118+ def is_serial_in_range (self , start : int , end : int , serial : int , * ,
119+ closed_start : bool = False ,
120+ closed_end : bool = False ) -> bool :
113121 return (
114122 ((end - start ) & 0xFF ) >= ((serial - start ) & 0xFF )
115123 and (closed_start or ((start - serial ) & 0xFF ) > 0 )
116124 and (closed_end or ((end - serial ) & 0xFF ) > 0 )
117125 )
118126
119- def inject_missed_move_to_buffer (self , move ) :
127+ def inject_missed_move_to_buffer (self , move : MoveEventDict ) -> None :
120128 if len (self .move_buffer ) > 0 :
121129 buffer_head = self .move_buffer [0 ]
122130
@@ -142,7 +150,7 @@ def inject_missed_move_to_buffer(self, move):
142150 ):
143151 self .move_buffer .insert (0 , move )
144152
145- async def check_if_move_missed (self ):
153+ async def check_if_move_missed (self ) -> None :
146154 diff = (self .serial - self .last_serial ) & 0xFF
147155
148156 if diff > 0 and self .serial != 0 :
@@ -152,12 +160,12 @@ async def check_if_move_missed(self):
152160 ) & 0xFF
153161 await self .request_move_history (start_serial , diff + 1 )
154162
155- async def event_handler (self , sender , data ) : # noqa: ARG002
163+ async def event_handler (self , sender : int , data : bytes ) -> list [ EventDict ] : # noqa: ARG002
156164 """Process notifications from the cube"""
157165 clock = time .perf_counter_ns ()
158166 timestamp = datetime .now (tz = timezone .utc ) # noqa: UP017
159167
160- events = []
168+ events : list [ EventDict ] = []
161169
162170 msg = GanProtocolMessage (
163171 self .cypher .decrypt (data ),
@@ -196,7 +204,9 @@ async def event_handler(self, sender, data): # noqa: ARG002
196204 'move' : move .strip (),
197205 },
198206 )
199- self .add_event (events , await self .evict_move_buffer ())
207+ evicted = await self .evict_move_buffer ()
208+ if evicted :
209+ self .add_event (events , cast (Sequence [dict [str , Any ]], evicted ))
200210
201211 elif event == 0x02 : # Facelets
202212 serial = msg .get_bit_word (24 , 16 , little_endian = True )
@@ -280,7 +290,9 @@ async def event_handler(self, sender, data): # noqa: ARG002
280290 },
281291 )
282292
283- self .add_event (events , await self .evict_move_buffer ())
293+ evicted = await self .evict_move_buffer ()
294+ if evicted :
295+ self .add_event (events , cast (Sequence [dict [str , Any ]], evicted ))
284296
285297 elif event == 0x07 : # Hardware
286298 sw_major = msg .get_bit_word (72 , 4 )
0 commit comments