Skip to content

add io layer #392

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

Merged
merged 22 commits into from
Feb 20, 2025
Merged

add io layer #392

merged 22 commits into from
Feb 20, 2025

Conversation

rickwierenga
Copy link
Member

This PR introduces a third layer of abstraction in PLR: the io layer. This will live in between backends and the physical reality. ALL communication of PLR with machines will go through this layer. Some IO objects will be thin wrappers, others will be more complicated.

Backends will now have an io attribute, similar to have frontends have a backend attribute. Backends will still be responsible for creating machine specific commands, but communication will be done in the io layer.

Why? This is for testing. If the communication that goes through the io layer doesn't change, it means we are communicating the same commands to the outside world: machines will do the same thing. Having ALL communication in this layer makes that easy. It is now easy to write integration tests. When you change something in your protocol or pull from plr:main, if the io layer sends and receives the same data, the protocol will be the same.

The source of truth is a log file generated during a real automation run (or a liquid test). This means that the protocol is proven to work in physical reality, otherwise you wouldn't get a log file (tempering is possible, but you're your own adversary). When you change your protocol, you can easily grab that new log file and make it the file that you validate against. No manually updating tests.

Checking happens through a central object called the LogReader. This reads the commands in a log file. The IO objects will then validate that if they receive a write command the data matches that in the log file. If they receive a read command they will check that in physical reality, the specific device actually returned some data (the validation object will then actually return this data so that the backend can function normally. The objects in the IO layer (USB, FTDI, Serial, ...) will all call into the single LogReader and request the next line. This ensures that not only do the IO objects read/write the correct information, they also do so in the right order. For example, the door on your cytomat is opened before the iswap puts the plate in, not after.

An added benefit of checking against log files is that more complicates sequences like step_off_foil will work even in testing. step_off_foil requests the channel positions and positions the channels based on that. Previously, it was impossible to test this function.

You can find an example notebook in docs/user_guide/validation.ipynb

@rickwierenga rickwierenga merged commit 6e48b50 into main Feb 20, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant