Skip to content

Commit 7153b7a

Browse files
committed
pybricksdev.connections.pybricks: add read_line and write_line methods
This methods make it very easy to work with text-based stdio on the hub (counterparts to print() and input()).
1 parent 078432b commit 7153b7a

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010
- Added support for Pybricks Profile v1.3.0.
11+
- Added new `PybricksHub.write_string()` method.
12+
- Added new `PybricksHub.write_line()` method.
13+
- Added new `PybricksHub.read_line()` method.
14+
1115
## [1.0.0-alpha.42] - 2023-04-12
1216

1317
### Fixed

pybricksdev/connections/pybricks.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)