-
Notifications
You must be signed in to change notification settings - Fork 180
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
feat(api): store labware objects in the stacker #18010
base: edge
Are you sure you want to change the base?
Conversation
5b923a8
to
3bac787
Compare
3bac787
to
d116172
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## edge #18010 +/- ##
=======================================
Coverage 62.01% 62.01%
=======================================
Files 2989 2989
Lines 232004 232004
Branches 20013 20013
=======================================
Hits 143885 143885
Misses 87942 87942
Partials 177 177
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
@dataclass | ||
class _LabwareDefPair: | ||
definition: LabwareDefinition | ||
id: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is labware id correct?
labware: LoadedLabware, | ||
) -> None: | ||
definitions_by_id[labware.id] = definition | ||
display_names_by_id[labware.id] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be None? we can get int from the definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor and new features look really great overall, thanks Seth! Stacker common is a bit massive now, but I think it makes sense for the logic to live there as opposed to split between retrieve/unsafe retrieve and store as it was. Logistical question, do we want to wait on this until the PAPI PR is up and merge them into eachother first before merging this to edge?
The structure for Labware group and location sequencing logic, as well as the changes to Store and Retrieve to track the contained labware groups make sense. Some notes below on some things I wanted to verify and also where we might need to change the app end logic since retrieve isn't the "loader" for labware anymore.
return group.lid.locationSequence | ||
|
||
|
||
def _check_one_preloaded_labware_known( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all seems like solid validation, should be zero cases of mixed state labware groups anyways so nice!
return False | ||
|
||
|
||
def _check_one_preloaded_labware( # noqa: C901 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but just wanted to verify one thing regarding lids. We are validating that lids must be on a labware location, but not that solo lids must be off deck. Are we fully planning to not distribute lids/lid stacks out of the stacker? We can always make that change later, not blocking.
.set_batch_loaded_labware( | ||
definitions_by_id=definitions_by_id, | ||
offset_ids_by_id=offset_ids_by_id, | ||
display_names_by_id=display_names_by_id, | ||
new_locations_by_id=new_locations_by_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine as is, but last time I was modifying how we split out some of the batch loaded labware behavior I was wondering if it would be better to just send a set of LoadedLabware objects right down the line through state update all the way to the labware store. No need to gut it now, but these various dicts just do the "breaking up" work here instead of down at the handler in the end, so we could in theory save all this for that end step. I think the only reason I didn't at the time is that the new_location_by_id dict had to exist for location sequences so I left it all be.
self._state_view, | ||
[ | ||
NotOnDeckLocationSequenceComponent( | ||
logicalLocationName=SYSTEM_LOCATION |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent, this aligns with the way in which we spawn new lid stack objects onto the deck during a move lid to empty deck slot command.
lid_def, | ||
) | ||
.update_flex_stacker_labware_pool_count(params.moduleId, count) | ||
state_update, new_contained_labware = await build_or_assign_labware_to_hopper( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need to update the client and our starting deck state logic to be aware that this is our new "source" of a load labware type of action instead of retrieve.
] | ||
|
||
|
||
def build_retrieve_labware_move_updates( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain the method name?
..., description="The number of labware loaded into the stacker labware pool." | ||
..., description="The number of labware now stored in the hopper." | ||
) | ||
originalPrimaryLabwareLocationSequences: ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be missing something but why do we need this prop in setStoredLabware command?
We had this beautiful dream: the stacker wouldn't store labware. Instead, the stacker would know what kind of labware it should store, and how many of those labware it is storing, and objects would be created when you retrieved stuff. The problem with that is in the physical world there are labware objects in the stacker, and if we're not modeling them you can't know the state of those physical objects. So we have to reverse this decision and store the identity of the labware in the stacker.
This PR is the set of changes to accomplish that in the engine and account for it in the python API; the ts bindings; and at least somewhat in the app interface that already exists. It won't add any new API or app stuff.
The way that this works is:
InStackerHopper(moduleId)
setStoredLabware
andfill
now handle making sure all the labware exists. They take lists of ids for PD compliance and also so that you can predefine labware if you want. They also still have a count argument. You cancount
, and the command will create that many labware with arbitrary IDsOFF_DECK
or there's an errorretrieve
doesn't create labware anymoreempty
, it's moved toOFF_DECK
fill
,setStoredLabware
, andempty
all now specify lots of labware location sequences and ids in their results because they create or move labware where they previously do not. Whenfill
andsetStoredLabware
create labware, they gloss those labware as having an original position descending toSYSTEM
. Otherwise, they're the real original locations.to come out of draft
Make commit names that aren't so sillythat's what the squash is forto merge
review requests
in addition to the standard stuff,