-
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(shared-data): create v3 JSON protocol schema def #3307
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,382 @@ | ||
{ | ||
"$id": "opentronsProtocolSchemaV3", | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
|
||
"definitions": { | ||
"pipetteName": { | ||
"description": "Name of a pipette. Does not contain info about specific model/version. Should match keys in pipetteNameSpecs.json", | ||
"type": "string", | ||
"enum": [ | ||
"p10_single", | ||
"p10_multi", | ||
"p50_single", | ||
"p50_multi", | ||
"p300_single", | ||
"p300_multi", | ||
"p1000_single", | ||
"p1000_multi" | ||
] | ||
}, | ||
|
||
"mmOffset": { | ||
"description": "Millimeters for pipette location offsets", | ||
"type": "number" | ||
}, | ||
|
||
"flowRateForPipettes": { | ||
"description": "Flow rate in mm/sec for each pipette used in the protocol, by pipette name", | ||
"type": "object", | ||
"propertyNames": {"$ref": "#/definitions/pipetteName"}, | ||
"patternProperties": {".*": {"type": "number"}}, | ||
"additionalProperties": false | ||
}, | ||
|
||
"flowRateParams": { | ||
"properties": { | ||
"flowRate": { | ||
"description": "Flow rate for aspirate/dispense. If omitted, defaults to the corresponding values in \"defaultValues\"", | ||
"type": "number" | ||
} | ||
} | ||
}, | ||
|
||
"offsetFromBottomMm": { | ||
"description": "Offset from bottom of well in millimeters", | ||
"properties": { | ||
"offsetFromBottomMm": {"$ref": "#/definitions/mmOffset"} | ||
} | ||
}, | ||
|
||
"pipetteAccessParams": { | ||
"required": ["pipette", "labware", "well"], | ||
"properties": { | ||
"pipette": { | ||
"type": "string" | ||
}, | ||
"labware": { | ||
"type": "string" | ||
}, | ||
"well": { | ||
"type": "string" | ||
} | ||
} | ||
}, | ||
|
||
"volumeParams": { | ||
"required": ["volume"], | ||
"volume": { | ||
"type": "number" | ||
} | ||
}, | ||
|
||
"slot": { | ||
"description": "Slot on the deck of an OT-2 robot", | ||
"type": "string", | ||
"enum": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"] | ||
} | ||
}, | ||
|
||
"type": "object", | ||
"additionalProperties": false, | ||
"required": [ | ||
"schemaVersion", | ||
"defaultValues", | ||
"metadata", | ||
"robot", | ||
"pipettes", | ||
"labware", | ||
"labwareDefinitions", | ||
"commands" | ||
], | ||
"properties": { | ||
"schemaVersion": { | ||
"description": "Schema version of a protocol is a single integer", | ||
"enum": [3] | ||
}, | ||
|
||
"metadata": { | ||
"description": "Optional metadata about the protocol", | ||
"type": "object", | ||
|
||
"properties": { | ||
"protocolName": { | ||
"description": "A short, human-readable name for the protocol", | ||
"type": "string" | ||
}, | ||
"author": { | ||
"description": "The author or organization who created the protocol", | ||
"type": "string" | ||
}, | ||
"description": { | ||
"description": "A text description of the protocol.", | ||
"type": ["string", "null"] | ||
}, | ||
|
||
"created": { | ||
"description": "UNIX timestamp when this file was created", | ||
"type": "number" | ||
}, | ||
"lastModified": { | ||
"description": "UNIX timestamp when this file was last modified", | ||
"type": ["number", "null"] | ||
}, | ||
|
||
"category": { | ||
"description": "Category of protocol (eg, \"Basic Pipetting\")", | ||
"type": ["string", "null"] | ||
}, | ||
"subcategory": { | ||
"description": "Subcategory of protocol (eg, \"Cell Plating\")", | ||
"type": ["string", "null"] | ||
}, | ||
"tags": { | ||
"description": "Tags to be used in searching for this protocol", | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
} | ||
} | ||
}, | ||
|
||
"defaultValues": { | ||
"description": "Default values required for protocol execution", | ||
"type": "object", | ||
"required": [ | ||
"aspirateFlowRate", | ||
"dispenseFlowRate", | ||
"aspirateMmFromBottom", | ||
"dispenseMmFromBottom", | ||
"touchTipMmFromTop" | ||
], | ||
"properties": { | ||
"aspirateFlowRate": {"$ref": "#/definitions/flowRateForPipettes"}, | ||
"dispenseFlowRate": {"$ref": "#/definitions/flowRateForPipettes"}, | ||
"aspirateMmFromBottom": {"$ref": "#/definitions/mmOffset"}, | ||
"dispenseMmFromBottom": {"$ref": "#/definitions/mmOffset"}, | ||
"touchTipMmFromTop": {"$ref": "#/definitions/mmOffset"} | ||
} | ||
}, | ||
|
||
"designerApplication": { | ||
"description": "Optional data & metadata not required to execute the protocol, used by the application that created this protocol", | ||
"type": "object", | ||
"properties": { | ||
"name": { | ||
"description": "Name of the application that created the protocol. Should be namespaced under the organization or individual who owns the organization, eg \"opentrons/protocol-designer\"", | ||
"type": "string" | ||
}, | ||
"version": { | ||
"description": "Version of the application that created the protocol", | ||
"type": "string" | ||
}, | ||
"data": { | ||
"description": "Any data used by the application that created this protocol)", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is that an extra closing paren? |
||
"type": "object" | ||
} | ||
} | ||
}, | ||
|
||
"robot": { | ||
"required": ["model"], | ||
"properties": { | ||
"model": { | ||
"description": "Model of the robot this protocol is written for (currently only OT-2 Standard is supported)", | ||
"type": "string", | ||
"enum": ["OT-2 Standard"] | ||
} | ||
} | ||
}, | ||
|
||
"pipettes": { | ||
"description": "The pipettes used in this protocol, keyed by an arbitrary unique ID", | ||
"additionalProperties": false, | ||
"patternProperties": { | ||
".+": { | ||
"description": "Fields describing an individual pipette", | ||
"type": "object", | ||
"required": ["mount", "name"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"mount": { | ||
"description": "Where the pipette is mounted", | ||
"type": "string", | ||
"enum": ["left", "right"] | ||
}, | ||
"name": { | ||
"$ref": "#/definitions/pipetteName" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
|
||
"labwareDefinitions": { | ||
"description": "All labware definitions used by labware in this protocol, keyed by UUID", | ||
"patternProperties": { | ||
".+": { | ||
"$ref": "opentronsLabwareSchemaV2" | ||
} | ||
} | ||
}, | ||
|
||
"labware": { | ||
"description": "All types of labware used in this protocol, and references to their definitions", | ||
"patternProperties": { | ||
".+": { | ||
"description": "Fields describing a single labware on the deck", | ||
"type": "object", | ||
"required": ["slot", "definitionId"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"slot": {"$ref": "#/definitions/slot"}, | ||
"definitionId": { | ||
"description": "reference to this labware's ID in \"labwareDefinitions\"", | ||
"type": "string" | ||
}, | ||
"displayName": { | ||
"description": "An optional human-readable nickname for this labware. Eg \"Buffer Trough\"", | ||
"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
|
||
"commands": { | ||
"description": "An array of command objects representing steps to be executed on the robot", | ||
"type": "array", | ||
"items": { | ||
"anyOf": [ | ||
{ | ||
"description": "Aspirate / dispense / air gap commands", | ||
"type": "object", | ||
"required": ["command", "params"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"command": { | ||
"enum": ["aspirate", "dispense", "airGap"] | ||
}, | ||
"params": { | ||
"allOf": [ | ||
{"$ref": "#/definitions/flowRateParams"}, | ||
{"$ref": "#/definitions/pipetteAccessParams"}, | ||
{"$ref": "#/definitions/volumeParams"}, | ||
{"$ref": "#/definitions/offsetFromBottomMm"} | ||
] | ||
} | ||
} | ||
}, | ||
|
||
{ | ||
"description": "Touch tip commands", | ||
"type": "object", | ||
"required": ["command", "params"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"command": { | ||
"enum": ["touchTip"] | ||
}, | ||
"params": { | ||
"allOf": [ | ||
{"$ref": "#/definitions/pipetteAccessParams"}, | ||
{"$ref": "#/definitions/offsetFromBottomMm"} | ||
] | ||
} | ||
} | ||
}, | ||
|
||
|
||
{ | ||
"description": "Pick up tip / drop tip / blowout commands", | ||
"type": "object", | ||
"required": ["command", "params"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"command": { | ||
"enum": ["pickUpTip", "dropTip", "blowout"] | ||
}, | ||
"params": { | ||
"allOf": [ | ||
{"$ref": "#/definitions/pipetteAccessParams"} | ||
] | ||
} | ||
} | ||
}, | ||
|
||
{ | ||
"description": "Move to slot command. NOTE: this is an EXPERIMENTAL command, its behavior is subject to change in future releases.", | ||
"type": "object", | ||
"required": ["command", "params"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"command": {"enum": ["moveToSlot"]}, | ||
"params": { | ||
"type": "object", | ||
"required": ["pipette", "slot"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"pipette": {"type": "string"}, | ||
"slot": {"$ref": "#/definitions/slot"}, | ||
"offset": { | ||
"description": "Optional offset from slot bottom left corner, in mm", | ||
"type": "object", | ||
"required": ["x", "y", "z"], | ||
"properties": { | ||
"x": {"type": "number"}, | ||
"y": {"type": "number"}, | ||
"z": {"type": "number"} | ||
} | ||
}, | ||
"minimumZHeight": { | ||
"description": "Optional minimal Z margin in mm. If this is larger than the API's default safe Z margin, it will make the arc higher. If it's smaller, it will have no effect. Specifying this for movements that would not arc (moving within the same well in the same labware) will cause an arc movement instead. This param only supported in API v2, API v1 will ignore it.", | ||
"type": "number", | ||
"minimum": 0 | ||
}, | ||
"forceDirect": { | ||
"description": "Default is false. If true, moving from one labware/well to another will not arc to the default safe z, but instead will move directly to the specified location. This will also force the 'minimumZHeight' param to be ignored. In APIv1, this will use strategy='direct', which moves first in X/Y plane and then in Z. In API v2, a 'direct' movement is in X/Y/Z simultaneously", | ||
"type": "boolean" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
|
||
{ | ||
"description": "Delay command", | ||
"type": "object", | ||
"required": ["command", "params"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"command": { | ||
"enum": ["delay"] | ||
}, | ||
"params": { | ||
"type": "object", | ||
"additionalProperties": false, | ||
"required": ["wait"], | ||
"properties": { | ||
"wait": { | ||
"description": "either a number of seconds to wait (fractional values OK), or `true` to wait indefinitely until the user manually resumes the protocol", | ||
"anyOf": [ | ||
{"type": "number"}, | ||
{"enum": [true]} | ||
] | ||
}, | ||
"message": { | ||
"description": "optional message describing the delay" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
] | ||
} | ||
}, | ||
|
||
"commandAnnotations": { | ||
"description": "An optional object of annotations associated with commands. Its usage has not yet been defined, so its shape is not enforced by this schema.", | ||
"type": "object" | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Out of curiosity, how hard would it be to have this reference the deck schema? This might be a nice change to start moving towards minimizing the sources of truth for slots.
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.
Hmmm... the
deckSchema.json
schema doesn't have a slot enum, that info isn't in the deck schema itself. I don't know if JSON Schema has a way to extract these strings from an ordinary data JSON (egshared-data/robot-data/decks/ot2Standard.json
), I think it can only reference other JSON schemas.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.
Aha that makes sense, good point.