-
Notifications
You must be signed in to change notification settings - Fork 179
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(protocol-designer): introduce new -locationUpdates #17414
Conversation
trashBinLocationUpdate = | ||
unoccupiedSlotForTrash === WASTE_CHUTE_CUTOUT ? {} : hardcodedTrashFlex | ||
unoccupiedSlotForTrash === WASTE_CHUTE_CUTOUT |
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.
Hey, what does unoccupiedSlotForTrash
mean?
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.
all this logic was copied over from the reducer. This is that bug you noticed where trashbins are not generated back to where the user had them if the user doesn't include any pipetting steps in their protocol. So unoccupiedSlotForTrash
looks for the first available slot to place the trash bin. It includes the waste chute as well because there was a bug one time where a customer had a labware in every slot except for D3 which had a staging area. trash bins can not go into D3 with a staging area so it had to be a waste chute auto-generated instead.
@@ -252,11 +222,27 @@ export const getAdditionalEquipmentLocationUpdate = ( | |||
trashBinLocationUpdate = { | |||
[trashBinId]: trashCutoutId as string, | |||
} | |||
// in case the user has no pipetting steps, auto-generate a trashBin or wasteChute entity for Flex | |||
} else if (isFlex && !hasWasteChuteCommands) { |
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.
Hm, I'm trying to understand the logic here. From your comment "in case the user has no pipetting steps, auto-generate a trashBin or wasteChute," it sounds like you want this section to run if there is no waste chute commands and no garbage bin commands, but this if-statement only tests for !hasWasteChuteCommands
. Should this section run if there is no waste chute commands, but there IS a garbage bin command?
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.
the first if
in the statement is checking for if there is a trash bin command in the protocol and populates the trashBinLocationUpdate
based off of those commands. This else if
is auto-generating a trash bin if there were no pipetting steps for a Flex protocol. It's specifically checking for a flex protocol and making sure there is no waste chute because its possible to have a waste chute instead of a trash bin. You must have 1 though.
"pythonName": "liquid_0", | ||
"liquidGroupId": "1" | ||
"liquidGroupId": "0", | ||
"pythonName": "liquid_1", |
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.
Hey, what's happening over here? I thought the liquid changes happened in the previous PR, so why is the ingredients
getting updated here now?
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.
when i updated these fixtures, i imported them back into PD and then exported (so i wouldn't have to manually add in the -locationUpdate
info. I think the liquid information doesn't have a set pattern in which it generates the keys, which is why this changed. i don't think that's an issue, right?
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.
It shouldn't be a problem.
I was also suspicious because I saw "pythonName": "liquid_0"
, and I thought we had decided that the numbering should start from liquid_1
, so I was curious how the _0
got there in the first place.
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.
ahh looking at this now, i see that the displayNames didn't get copied over and you're right that the pythonName is wrong... weird. i didn't change the liquidEntities in this pr 🤔 i'll look into it. it seems like a bug with my liquidEntities
pr
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.
hmm what's weird is this is the only migration fixture with this issue... hmmmmm
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.
ok i think the actual issue was the migration fixture file was a bit corrupted. i fixed it by using the file from a much older commit (before i made the ingredient
changes) and importing that into the app and exporting 😄
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.
Hey, still working through this, but wanted to send you some more questions I had:
"pythonName": "liquid_0", | ||
"liquidGroupId": "1" | ||
"liquidGroupId": "0", | ||
"pythonName": "liquid_1", |
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.
It shouldn't be a problem.
I was also suspicious because I saw "pythonName": "liquid_0"
, and I thought we had decided that the numbering should start from liquid_1
, so I was curious how the _0
got there in the first place.
}, | ||
} | ||
} | ||
return acc |
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.
Hm, I'm confused: Is updatedInitialStep
supposed to be the entire savedStepForms
with __INITIAL_DECK_SETUP_STEP__
replaced, or is it supposed to be just the __INITIAL_DECK_SETUP_STEP__
entry?
In the base case down here, where you just return acc
, won't that just discard any entries that are NOT __INITIAL_DECK_SETUP_STEP__
? So I don't understand why this should use a reducer in the first place.
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.
its only updating the __INITIAL_DECK_SETUP_STEP__
entry! If you look at the return at the end of the function, i'm spreading in the remaining stepForms
:
savedStepForms: {
...designerApplication.data.savedStepForms,
...updatedInitialStep,
...savedStepsWithUpdatedMoveLiquidFields,
...savedStepsWithUpdatedMixFields,
},
return null | ||
} | ||
|
||
for (const stepForm of Object.values(savedStepForms)) { |
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.
Hey, how did you decide on the approach to extract the trashbin from the savedStepForms
instead of the commands
?
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.
the commands don't have the trashBinId
that is associated with the step forms. If we generated new trashBinIds
, the protocol would error on the trash bin steps because it would be looking for a different id. Same goes for waste chute.
if (stepForm.dropTip_location.toLowerCase().includes('trash')) { | ||
return stepForm.dropTip_location | ||
} | ||
if (stepForm.blowout_location?.toLowerCase().includes('trash')) { |
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.
Why is blowout_location
special -- why does it need blowout_location?.toLowerCase()
?
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.
you can blowout in the source well, destination well, or trash!
|
||
for (const stepForm of Object.values(savedStepForms)) { | ||
if (stepForm.stepType === 'moveLiquid') { | ||
if (stepForm.dispense_labware.toLowerCase().includes('trash')) { |
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.
Hm, should we add some more structure to the includes
string to make sure we don't get false matches? Like, do trashbins always have the ID :trash
?
(Hehe, I searched through my dictionary, and found words like intrashop
and ultrashrewd
.)
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 guess the ids should always end in :trashBin
so i can extend this to look for trashBin
. Alternatively, i could see if dispense_labware
is listed in the load labware commands (since labwareId
is a load labware command param. If it is not, then we know the dispense is happening in a trashBin or a wasteChute. But to narrow down if it is a trashBin or wasteChute, I don't think there is any other way since we have no idea what the trashBin
or wasteChute
id is without searching for it like this.
return { | ||
...form, | ||
[locationUpdate]: | ||
Object.keys(updatedLocation).length > 0 ? updatedLocation : {}, |
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.
Is the length > 0
necessary? Wouldn't [locationUpdate]: updatedLocation
be correct in all cases?
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 think it is since you can have multiple staging areas!
closes AUTH-1396
Overview
The goal of this PR is so when importing JSON/python protocols back into PD, we can determine the additionalEquipment entities from
stepForms
instead of reading the commands.This PR introduces a few new
-locationUpdate
keys insavedStepForms
'sINITIAL_DECK_SETUP_STEP
step. The locations include:trashBinLocationUpdate
wasteChuteLocationUpdate
gripperLocationUpdate
stagingAreaLocationUpdate
Each of them include the entity's id as the key and the location as the value. This is for pd/py interop so we can easily grab these additional equipment entities from the step forms instead of reading from the commands
Test Plan and Hands on Testing
Test this out with different variations of deleting/adding gripper, staging areas, trash bin/waste chute. and then import old versions of PD and test that the migration works as expected.
I did smoke test this a lot so i think everything is working as expected.
Changelog
add the new
locationUpdate
keys in stepForms for py/pd interop and wire it up in the reducerfix fixtures for the migration cypress test
Risk assessment
low-ish, will be well tested before merging