diff --git a/pylabrobot/io/capture.py b/pylabrobot/io/capture.py index 62244cb363..afda7cdc25 100644 --- a/pylabrobot/io/capture.py +++ b/pylabrobot/io/capture.py @@ -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 diff --git a/pylabrobot/io/ftdi.py b/pylabrobot/io/ftdi.py index 3bce5c72c6..7d94b6cf03 100644 --- a/pylabrobot/io/ftdi.py +++ b/pylabrobot/io/ftdi.py @@ -163,7 +163,7 @@ async def setup(self): pass async 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 @@ -173,7 +173,7 @@ async def set_baudrate(self, baudrate: int): raise ValidationError(f"Next line is {next_command}, expected FTDI set_baudrate {baudrate}") async 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 @@ -183,7 +183,7 @@ async def set_rts(self, level: bool): raise ValidationError(f"Next line is {next_command}, expected FTDI set_rts {level}") async 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 @@ -193,7 +193,7 @@ async def set_dtr(self, level: bool): raise ValidationError(f"Next line is {next_command}, expected FTDI set_dtr {level}") async 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 @@ -204,7 +204,7 @@ async def usb_reset(self): ) async 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 @@ -216,7 +216,7 @@ async def set_latency_timer(self, latency: int): ) async 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 @@ -228,7 +228,7 @@ async def set_line_property(self, bits: int, stopbits: int, parity: int): ) async 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 @@ -238,7 +238,7 @@ async def set_flowctrl(self, flowctrl: int): raise ValidationError(f"Next line is {next_command}, expected FTDI set_flowctrl {flowctrl}") async 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 @@ -249,7 +249,7 @@ async def usb_purge_rx_buffer(self): ) async 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 @@ -260,7 +260,7 @@ async def usb_purge_tx_buffer(self): ) async 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 @@ -272,7 +272,7 @@ async 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 @@ -284,7 +284,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 @@ -295,7 +295,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 diff --git a/pylabrobot/io/serial.py b/pylabrobot/io/serial.py index b2706182cf..5609102ba5 100644 --- a/pylabrobot/io/serial.py +++ b/pylabrobot/io/serial.py @@ -220,7 +220,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 @@ -232,18 +232,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 diff --git a/pylabrobot/io/usb.py b/pylabrobot/io/usb.py index 768da645a5..91383033aa 100644 --- a/pylabrobot/io/usb.py +++ b/pylabrobot/io/usb.py @@ -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 @@ -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