@@ -333,8 +333,59 @@ def handle_disconnect(state: ConnectionState):
333333
334334 return awaitable_task .result ()
335335
336- async def write (self , data , with_response = False ):
337- await self .client .write_gatt_char (NUS_RX_UUID , bytearray (data ), with_response )
336+ async def write (self , data : bytes ) -> None :
337+ """
338+ Writes raw data to stdin on the hub.
339+
340+ This is a low-level function to send a single write command over
341+ Bluetooth. Most users will want to use :meth:`write_string()` or
342+ :meth:`write_line()` instead.
343+
344+ Args:
345+ data: Any bytes-like object that will fit in a single BLE packet.
346+ """
347+ if self ._legacy_stdio :
348+ await self .client .write_gatt_char (NUS_RX_UUID , data , False )
349+ else :
350+ msg = bytearray ([Command .WRITE_STDIN ])
351+ msg .extend (data )
352+
353+ if len (msg ) > self ._max_write_size :
354+ raise ValueError (
355+ f"data is too big, limited to { self ._max_write_size - 1 } bytes"
356+ )
357+
358+ await self .client .write_gatt_char (PYBRICKS_COMMAND_EVENT_UUID , msg , True )
359+
360+ async def write_string (self , value : str ) -> None :
361+ """
362+ Writes a string to stdin on the hub.
363+
364+ Args:
365+ value: The string to write.
366+ """
367+
368+ for c in chunk (value .encode (), self ._max_write_size - 1 ):
369+ await self .write (c )
370+
371+ async def write_line (self , value : str ) -> None :
372+ """
373+ Writes a string to stdin on the hub and adds a newline (``\\ r\\ n``)
374+ to the end.
375+
376+ Args:
377+ value: The string to write.
378+ """
379+ await self .write_string (value + self .EOL .decode ())
380+
381+ async def read_line (self ) -> str :
382+ """
383+ Waits for a line to be read from stdout on the hub.
384+
385+ Returns:
386+ The next line read from stdout (without the newline).
387+ """
388+ return await self .race_disconnect (self ._stdout_line_queue .get ())
338389
339390 async def run (
340391 self , py_path : str , wait : bool = True , print_output : bool = True
0 commit comments