responding to @vcjdeboer
if
read_positionsreceives dataclasses (name + coordinate) rather than live PLR objects, the backend boundary becomes serializable. If we applied that principle across all capabilities — liquid handling, arms, shaking — the entire driver interface would be serializable by design. That would make @koeng protobuf/networking* work significantly easier (no custom converters), and it also makes drivers easier to test (just pass in data, no need to construct a full resource tree) and easier to write for new contributors (the driver contract is explicit about what data it needs).
from Modeling plate reading capabilities - #3 by vcjdeboer
serialize backend calls are indeed easier when we make this networked.
resources are technically serializable, but it’s a bit of a mess since they link to the resource of the resource system (up and down the tree). so in the rest of this post I will say “serializable” meaning non-resource data types.
The major challenge with this is that some backend methods like aspirate require a LOT of information, especially about container/well geometry, for like “start lld search height”, which is not a backend kwarg (which we could also define to be serializable) but actually inferred from the container geometry that is passed to the function. So not created on the front end or passed by the user. This type of behavior makes requiring serialization difficult. However, we could imagine the front end computing ALL of this information and passing it to all backends, and then backends deciding to use it or not. Other backends might have similar concepts, and some might ignore it.
A second challenge with requiring serializable backend commands is that making everything serialized is an even harder problem. Some star methods like probe_liquid_heights, backend specific methods that require resource models to be passed. If we want a “serializable” layer, then we would need to split this function somewhere.
This point is more about middleware/quality of life, but let’s say the backends only receive “aspirate at XYZ” rather than “aspirate at container C”, tracking would be more difficult for them. At that point, you might also just put the networking layer at sending firmware commands.
Third, we would already need to pass resources at some point since the backends will need to know what the resources look like. Or at the very least the server needs to know this for it to be useful. I always imagined I would have a single server running for my incubators where there is a web interface showing all plates, which users can edit, and then protocols (clients) just syncing the incubator server and loading plates from it. Since we will already have server side knowledge of resources, you could also imagine serializing resources by name and the server loading them from their own memory.