55import serial
66import serial_asyncio
77
8+ from bellows .thread import EventLoopThread , ThreadsafeProxy
9+
810import bellows .types as t
911
1012LOGGER = logging .getLogger (__name__ )
@@ -27,7 +29,7 @@ class Gateway(asyncio.Protocol):
2729 class Terminator :
2830 pass
2931
30- def __init__ (self , application , connected_future = None ):
32+ def __init__ (self , application , connected_future = None , connection_done_future = None ):
3133 self ._send_seq = 0
3234 self ._rec_seq = 0
3335 self ._buffer = b''
@@ -36,6 +38,7 @@ def __init__(self, application, connected_future=None):
3638 self ._connected_future = connected_future
3739 self ._sendq = asyncio .Queue ()
3840 self ._pending = (- 1 , None )
41+ self ._connection_done_future = connection_done_future
3942
4043 def connection_made (self , transport ):
4144 """Callback when the uart is connected"""
@@ -173,20 +176,22 @@ def _reset_cleanup(self, future):
173176
174177 def connection_lost (self , exc ):
175178 """Port was closed unexpectedly."""
179+ if self ._connection_done_future :
180+ self ._connection_done_future .set_result (exc )
176181 if exc is None :
177182 LOGGER .debug ("Closed serial connection" )
178183 return
179184
180185 LOGGER .error ("Lost serial connection: %s" , exc )
181186 self ._application .connection_lost (exc )
182187
183- def reset (self ):
188+ async def reset (self ):
184189 """Send a reset frame and init internal state."""
185190 LOGGER .debug ("Resetting ASH" )
186191 if self ._reset_future is not None :
187192 LOGGER .error (("received new reset request while an existing "
188193 "one is in progress" ))
189- return self ._reset_future
194+ return await self ._reset_future
190195
191196 self ._send_seq = 0
192197 self ._rec_seq = 0
@@ -197,10 +202,10 @@ def reset(self):
197202 self ._pending [1 ].set_result (True )
198203 self ._pending = (- 1 , None )
199204
200- self ._reset_future = asyncio .Future ()
205+ self ._reset_future = asyncio .get_event_loop (). create_future ()
201206 self ._reset_future .add_done_callback (self ._reset_cleanup )
202207 self .write (self ._rst_frame ())
203- return asyncio .wait_for (self ._reset_future , timeout = RESET_TIMEOUT )
208+ return await asyncio .wait_for (self ._reset_future , timeout = RESET_TIMEOUT )
204209
205210 async def _send_task (self ):
206211 """Send queue handler"""
@@ -212,7 +217,7 @@ async def _send_task(self):
212217 success = False
213218 rxmit = 0
214219 while not success :
215- self ._pending = (seq , asyncio .Future ())
220+ self ._pending = (seq , asyncio .get_event_loop (). create_future ())
216221 self .write (self ._data_frame (data , seq , rxmit ))
217222 rxmit = 1
218223 success = await self ._pending [1 ]
@@ -305,12 +310,12 @@ def _unstuff(self, s):
305310 return out
306311
307312
308- async def connect (port , baudrate , application , loop = None ):
309- if loop is None :
310- loop = asyncio .get_event_loop ()
313+ async def _connect (port , baudrate , application ):
314+ loop = asyncio .get_event_loop ()
311315
312- connection_future = asyncio .Future ()
313- protocol = Gateway (application , connection_future )
316+ connection_future = loop .create_future ()
317+ connection_done_future = loop .create_future ()
318+ protocol = Gateway (application , connection_future , connection_done_future )
314319
315320 transport , protocol = await serial_asyncio .create_serial_connection (
316321 loop ,
@@ -324,4 +329,17 @@ async def connect(port, baudrate, application, loop=None):
324329
325330 await connection_future
326331
332+ thread_safe_protocol = ThreadsafeProxy (protocol , loop )
333+ return thread_safe_protocol , connection_done_future
334+
335+
336+ async def connect (port , baudrate , application , use_thread = True ):
337+ if use_thread :
338+ application = ThreadsafeProxy (application , asyncio .get_event_loop ())
339+ thread = EventLoopThread ()
340+ await thread .start ()
341+ protocol , connection_done = await thread .run_coroutine_threadsafe (_connect (port , baudrate , application ))
342+ connection_done .add_done_callback (lambda _ : thread .force_stop ())
343+ else :
344+ protocol , _ = await _connect (port , baudrate , application )
327345 return protocol
0 commit comments