diff --git a/pylabrobot/centrifuge/centrifuge.py b/pylabrobot/centrifuge/centrifuge.py index d2598b75a5..fbddb92f0f 100644 --- a/pylabrobot/centrifuge/centrifuge.py +++ b/pylabrobot/centrifuge/centrifuge.py @@ -1,7 +1,9 @@ +from typing import cast from pylabrobot.machines.machine import Machine from pylabrobot.centrifuge.backend import CentrifugeBackend, LoaderBackend from pylabrobot.resources.coordinate import Coordinate from pylabrobot.resources.resource_holder import ResourceHolder +from pylabrobot.serializer import serialize, deserialize class Centrifuge(Machine): @@ -62,7 +64,9 @@ class Loader(Machine, ResourceHolder): """The front end for centrifuge loaders. Centrifuge loaders are devices that can load and unload samples from centrifuges.""" - def __init__(self, backend: LoaderBackend, centrifuge: Centrifuge, stage_location: Coordinate) -> None: + def __init__( + self, backend: LoaderBackend, centrifuge: Centrifuge, stage_location: Coordinate + ) -> None: super().__init__(backend=backend) self.backend: LoaderBackend = backend # fix type self.centrifuge: Centrifuge = centrifuge @@ -80,3 +84,25 @@ async def unload(self) -> None: if not self.centrifuge.door_open: raise CentrifugeDoorError("Centrifuge door must be open to unload a plate.") await self.backend.unload() + + def serialize(self) -> dict: + return { + **super().serialize(), + "resource": ResourceHolder.serialize(self), + "machine": Machine.serialize(self), + "centrifuge": self.centrifuge.serialize(), + "stage_location": serialize(self.stage_location), + } + + @classmethod + def deserialize(cls, data: dict, allow_marshall: bool = False): + data_copy = data.copy() # copy data because we will be modifying it + centrifuge_data = data_copy.pop("centrifuge") + centrifuge = Centrifuge.deserialize(centrifuge_data) + stage_location_data = data_copy.pop("stage_location") + stage_location = cast(Coordinate, deserialize(stage_location_data)) + return cls( + centrifuge=centrifuge, + stage_location=stage_location, + **data_copy, + ) diff --git a/pylabrobot/centrifuge/vspin.py b/pylabrobot/centrifuge/vspin.py index cf1504fd4f..f29fc99dc7 100644 --- a/pylabrobot/centrifuge/vspin.py +++ b/pylabrobot/centrifuge/vspin.py @@ -33,7 +33,7 @@ def __init__(self, centrifuge: "VSpin", device_id: str, timeout: int = 60): self.dev = Device(lazy_open=True, device_id=device_id) self.timeout = timeout - async def _read(self): + async def _read(self) -> bytes: x = b"" r = None start = time.time() @@ -46,10 +46,10 @@ async def _read(self): raise TimeoutError("No data received within the specified timeout period") return x - def send_command(self, command: bytes): + async def send_command(self, command: bytes) -> bytes: logger.debug("[loader] Sending %s", command.hex()) self.dev.write(command) - return self._read() + return await self._read() async def setup(self): logger.debug("[loader] setup") @@ -137,9 +137,7 @@ class VSpin(CentrifugeBackend): """Backend for the Agilent Centrifuge. Note that this is not a complete implementation.""" - def __init__( - self, bucket_1_position: int, device_id: Optional[str] = None, loader: Optional[Loader] = None - ): + def __init__(self, bucket_1_position: int, device_id: Optional[str] = None): """ Args: device_id: The libftdi id for the centrifuge. Find using