Skip to content

Support async io validation #481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions pylabrobot/io/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,34 +85,37 @@ def capture_active(self):
class CaptureReader:
def __init__(self, path: str):
self.path = path
self.commands: List[dict] = []
self.commands: dict[str, List[dict]] = {}
with open(path, "r") as f:
data = json.load(f)
for c in data["commands"]:
self.commands.append(c)
self._command_idx = 0
if c.get("device_id") not in self.commands:
self.commands[c["device_id"]] = []
self.commands[c["device_id"]].append(c)
self._command_idx = {k: 0 for k in self.commands.keys()}

def start(self):
global _capture_or_validation_active
_capture_or_validation_active = True

def next_command(self) -> dict:
command = self.commands[self._command_idx]
self._command_idx += 1
def next_command(self, device_id) -> dict:
print("getting next command for device", device_id)
command = self.commands[device_id][self._command_idx[device_id]]
self._command_idx[device_id] += 1
return command

def done(self):
if self._command_idx < len(self.commands):
left = len(self.commands) - self._command_idx
next_command = self.commands[self._command_idx]
raise ValidationError(
f"Log file not fully read, {left} lines left. First command: {next_command}"
)
# if self._command_idx < len(self.commands):
# left = len(self.commands) - self._command_idx
# next_command = self.commands[self._command_idx]
# raise ValidationError(
# f"Log file not fully read, {left} lines left. First command: {next_command}"
# )
print("Validation successful!")
self.reset()

def reset(self):
self._command_idx = 0
self._command_idx = {k: 0 for k in self.commands.keys()}

global _capture_or_validation_active
_capture_or_validation_active = True
Expand Down
26 changes: 13 additions & 13 deletions pylabrobot/io/ftdi.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ async def setup(self):
pass

def set_baudrate(self, baudrate: int):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -152,7 +152,7 @@ def set_baudrate(self, baudrate: int):
raise ValidationError(f"Next line is {next_command}, expected FTDI set_baudrate {baudrate}")

def set_rts(self, level: bool):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -162,7 +162,7 @@ def set_rts(self, level: bool):
raise ValidationError(f"Next line is {next_command}, expected FTDI set_rts {level}")

def set_dtr(self, level: bool):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -172,7 +172,7 @@ def set_dtr(self, level: bool):
raise ValidationError(f"Next line is {next_command}, expected FTDI set_dtr {level}")

def usb_reset(self):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -183,7 +183,7 @@ def usb_reset(self):
)

def set_latency_timer(self, latency: int):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -195,7 +195,7 @@ def set_latency_timer(self, latency: int):
)

def set_line_property(self, bits: int, stopbits: int, parity: int):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -207,7 +207,7 @@ def set_line_property(self, bits: int, stopbits: int, parity: int):
)

def set_flowctrl(self, flowctrl: int):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -217,7 +217,7 @@ def set_flowctrl(self, flowctrl: int):
raise ValidationError(f"Next line is {next_command}, expected FTDI set_flowctrl {flowctrl}")

def usb_purge_rx_buffer(self):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -228,7 +228,7 @@ def usb_purge_rx_buffer(self):
)

def usb_purge_tx_buffer(self):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -239,7 +239,7 @@ def usb_purge_tx_buffer(self):
)

def poll_modem_status(self) -> int:
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -251,7 +251,7 @@ def poll_modem_status(self) -> int:
return int(next_command.data)

async def write(self, data: bytes):
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -263,7 +263,7 @@ async def write(self, data: bytes):
raise ValidationError("Data mismatch: difference was written to stdout.")

async def read(self, num_bytes: int = 1) -> bytes:
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand All @@ -274,7 +274,7 @@ async def read(self, num_bytes: int = 1) -> bytes:
return bytes.fromhex(next_command.data)

async def readline(self) -> bytes: # type: ignore # very dumb it's reading from pyserial
next_command = FTDICommand(**self.cr.next_command())
next_command = FTDICommand(**self.cr.next_command(self._device_id))
if not (
next_command.module == "ftdi"
and next_command.device_id == self._device_id
Expand Down
8 changes: 4 additions & 4 deletions pylabrobot/io/serial.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ async def setup(self):
pass

async def write(self, data: bytes):
next_command = SerialCommand(**self.cr.next_command())
next_command = SerialCommand(**self.cr.next_command(self._port))
if not (
next_command.module == "serial"
and next_command.device_id == self._port
Expand All @@ -182,18 +182,18 @@ async def write(self, data: bytes):
raise ValidationError("Data mismatch: difference was written to stdout.")

async def read(self, num_bytes: int = 1) -> bytes:
next_command = SerialCommand(**self.cr.next_command())
next_command = SerialCommand(**self.cr.next_command(self._port))
if not (
next_command.module == "serial"
and next_command.device_id == self._port
and next_command.action == "read"
and len(next_command.data) == num_bytes
and len(next_command.data) <= num_bytes # we can actually read less bytes than requested
):
raise ValidationError(f"Next line is {next_command}, expected Serial read {num_bytes}")
return next_command.data.encode()

async def readline(self) -> bytes: # type: ignore # very dumb it's reading from pyserial
next_command = SerialCommand(**self.cr.next_command())
next_command = SerialCommand(**self.cr.next_command(self._port))
if not (
next_command.module == "serial"
and next_command.device_id == self._port
Expand Down
4 changes: 2 additions & 2 deletions pylabrobot/io/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ async def setup(self):
pass

async def write(self, data: bytes, timeout: Optional[float] = None):
next_command = USBCommand(**self.cr.next_command())
next_command = USBCommand(**self.cr.next_command(self._unique_id))
if not (
next_command.module == "usb"
and next_command.device_id == self._unique_id
Expand All @@ -415,7 +415,7 @@ async def write(self, data: bytes, timeout: Optional[float] = None):
raise ValidationError("Data mismatch: difference was written to stdout.")

async def read(self, timeout: Optional[float] = None) -> bytes:
next_command = USBCommand(**self.cr.next_command())
next_command = USBCommand(**self.cr.next_command(self._unique_id))
if not (
next_command.module == "usb"
and next_command.device_id == self._unique_id
Expand Down
Loading