@opentrons/shared-data 0.0.1-alpha.20 → 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/Makefile +1 -1
  2. package/lib/opentrons-shared-data.js +1 -1
  3. package/lib/opentrons-shared-data.js.map +1 -1
  4. package/package.json +1 -1
  5. package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
  6. package/js/__tests__/deckSchemas.test.ts +0 -87
  7. package/js/__tests__/errors.test.js +0 -21
  8. package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
  9. package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
  10. package/js/__tests__/labwareDefQuirks.test.ts +0 -37
  11. package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
  12. package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
  13. package/js/__tests__/moduleAccessors.test.ts +0 -50
  14. package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
  15. package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
  16. package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
  17. package/js/__tests__/pipettes.test.ts +0 -58
  18. package/js/__tests__/protocolSchemaV4.test.ts +0 -137
  19. package/js/__tests__/protocolSchemaV5.test.ts +0 -137
  20. package/js/__tests__/protocolSchemaV6.test.ts +0 -132
  21. package/js/__tests__/protocolSchemaV7.test.ts +0 -64
  22. package/js/__tests__/protocolValidation.test.ts +0 -83
  23. package/js/__tests__/sortWells.test.ts +0 -40
  24. package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
  25. package/js/__tests__/validateErrors.test.js +0 -34
  26. package/js/constants.ts +0 -338
  27. package/js/cypressUtils.ts +0 -35
  28. package/js/errors.ts +0 -33
  29. package/js/fixtures.ts +0 -161
  30. package/js/getLabware.ts +0 -154
  31. package/js/gripper.ts +0 -29
  32. package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
  33. package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
  34. package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
  35. package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
  36. package/js/helpers/__tests__/labwareInference.test.ts +0 -84
  37. package/js/helpers/__tests__/orderWells.test.ts +0 -87
  38. package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
  39. package/js/helpers/__tests__/volume.test.ts +0 -108
  40. package/js/helpers/__tests__/wellSets.test.ts +0 -352
  41. package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
  42. package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
  43. package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
  44. package/js/helpers/getModuleVizDims.ts +0 -118
  45. package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
  46. package/js/helpers/getVectorDifference.ts +0 -12
  47. package/js/helpers/getVectorSum.ts +0 -12
  48. package/js/helpers/getWellNamePerMultiTip.ts +0 -86
  49. package/js/helpers/getWellTotalVolume.ts +0 -16
  50. package/js/helpers/index.ts +0 -347
  51. package/js/helpers/labwareInference.ts +0 -92
  52. package/js/helpers/orderWells.ts +0 -69
  53. package/js/helpers/parseProtocolData.ts +0 -141
  54. package/js/helpers/volume.ts +0 -35
  55. package/js/helpers/wellIsRect.ts +0 -6
  56. package/js/helpers/wellSets.ts +0 -155
  57. package/js/index.ts +0 -14
  58. package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
  59. package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
  60. package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
  61. package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
  62. package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
  63. package/js/labwareTools/index.ts +0 -452
  64. package/js/modules.ts +0 -97
  65. package/js/pipettes.ts +0 -89
  66. package/js/protocols.ts +0 -290
  67. package/js/schema.ts +0 -80
  68. package/js/scripts/generateDeckLayersFromSVG.js +0 -46
  69. package/js/titleCase.ts +0 -30
  70. package/js/types.ts +0 -600
  71. package/python/.coveragerc +0 -4
  72. package/python/.flake8 +0 -32
  73. package/python/Config.in +0 -10
  74. package/python/Makefile +0 -134
  75. package/python/Pipfile +0 -28
  76. package/python/Pipfile.lock +0 -645
  77. package/python/buildroot.mk +0 -30
  78. package/python/mypy.ini +0 -41
  79. package/python/opentrons_shared_data/__init__.py +0 -17
  80. package/python/opentrons_shared_data/_version.py +0 -20
  81. package/python/opentrons_shared_data/command/__init__.py +0 -52
  82. package/python/opentrons_shared_data/deck/__init__.py +0 -96
  83. package/python/opentrons_shared_data/deck/dev_types.py +0 -180
  84. package/python/opentrons_shared_data/errors/__init__.py +0 -30
  85. package/python/opentrons_shared_data/errors/categories.py +0 -60
  86. package/python/opentrons_shared_data/errors/codes.py +0 -108
  87. package/python/opentrons_shared_data/errors/exceptions.py +0 -915
  88. package/python/opentrons_shared_data/gripper/__init__.py +0 -63
  89. package/python/opentrons_shared_data/gripper/constants.py +0 -6
  90. package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
  91. package/python/opentrons_shared_data/labware/__init__.py +0 -22
  92. package/python/opentrons_shared_data/labware/constants.py +0 -7
  93. package/python/opentrons_shared_data/labware/dev_types.py +0 -140
  94. package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
  95. package/python/opentrons_shared_data/load.py +0 -57
  96. package/python/opentrons_shared_data/module/__init__.py +0 -74
  97. package/python/opentrons_shared_data/module/dev_types.py +0 -141
  98. package/python/opentrons_shared_data/pipette/__init__.py +0 -107
  99. package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
  100. package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
  101. package/python/opentrons_shared_data/pipette/load_data.py +0 -261
  102. package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
  103. package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
  104. package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
  105. package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
  106. package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
  107. package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
  108. package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
  109. package/python/opentrons_shared_data/pipette/types.py +0 -193
  110. package/python/opentrons_shared_data/protocol/__init__.py +0 -13
  111. package/python/opentrons_shared_data/protocol/constants.py +0 -98
  112. package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
  113. package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
  114. package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
  115. package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
  116. package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
  117. package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
  118. package/python/opentrons_shared_data/py.typed +0 -0
  119. package/python/opentrons_shared_data/robot/__init__.py +0 -33
  120. package/python/opentrons_shared_data/robot/dev_types.py +0 -37
  121. package/python/pytest.ini +0 -2
  122. package/python/setup.cfg +0 -5
  123. package/python/setup.py +0 -179
  124. package/python/tests/__init__.py +0 -1
  125. package/python/tests/conftest.py +0 -0
  126. package/python/tests/deck/__init__.py +0 -0
  127. package/python/tests/deck/test_list_names.py +0 -12
  128. package/python/tests/deck/test_position.py +0 -113
  129. package/python/tests/deck/test_typechecks.py +0 -28
  130. package/python/tests/errors/__init__.py +0 -1
  131. package/python/tests/errors/test_error_completeness.py +0 -19
  132. package/python/tests/errors/test_exceptions.py +0 -74
  133. package/python/tests/gripper/__init__.py +0 -0
  134. package/python/tests/gripper/test_definition.py +0 -30
  135. package/python/tests/gripper/test_load.py +0 -16
  136. package/python/tests/labware/__init__.py +0 -13
  137. package/python/tests/labware/test_typechecks.py +0 -21
  138. package/python/tests/module/__init__.py +0 -20
  139. package/python/tests/module/test_load.py +0 -49
  140. package/python/tests/module/test_typechecks.py +0 -34
  141. package/python/tests/pipette/__init__.py +0 -0
  142. package/python/tests/pipette/test_load_data.py +0 -103
  143. package/python/tests/pipette/test_mutable_configurations.py +0 -266
  144. package/python/tests/pipette/test_pipette_definition.py +0 -183
  145. package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
  146. package/python/tests/pipette/test_typechecks.py +0 -50
  147. package/python/tests/pipette/test_validate_schema.py +0 -37
  148. package/python/tests/protocol/__init__.py +0 -15
  149. package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
  150. package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
  151. package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
  152. package/python/tests/protocol/test_typechecks.py +0 -36
  153. package/python/tests/robot/__init__.py +0 -0
  154. package/python/tests/robot/test_typechecks.py +0 -20
@@ -1,915 +0,0 @@
1
- """Exception hierarchy for error codes."""
2
- from typing import Dict, Any, Optional, List, Iterator, Union, Sequence
3
- from logging import getLogger
4
- from traceback import format_exception_only, format_tb
5
- import inspect
6
- import sys
7
-
8
- from .codes import ErrorCodes
9
- from .categories import ErrorCategories
10
-
11
-
12
- log = getLogger(__name__)
13
-
14
-
15
- class EnumeratedError(Exception):
16
- """The root class of error-code-bearing exceptions."""
17
-
18
- def __init__(
19
- self,
20
- code: ErrorCodes,
21
- message: Optional[str] = None,
22
- detail: Optional[Dict[str, str]] = None,
23
- wrapping: Optional[Sequence["EnumeratedError"]] = None,
24
- ) -> None:
25
- """Build an EnumeratedError."""
26
- self.code = code
27
- self.message = message or ""
28
- self.detail = detail or {}
29
- self.wrapping = wrapping or []
30
-
31
- def __repr__(self) -> str:
32
- """Get a representative string for the exception."""
33
- return f"<{self.__class__.__name__}: code=<{self.code.value.code} {self.code.name}> message={self.message} detail={str(self.detail)}"
34
-
35
- def __str__(self) -> str:
36
- """Get a human-readable string."""
37
- _node = self.detail.get("node")
38
- return f'Error {self.code.value.code} {self.code.name} ({self.__class__.__name__}){f": {self.message}" if self.message else ""}{f" ({_node})" if _node else ""}'
39
-
40
- def __eq__(self, other: object) -> bool:
41
- """Compare if two enumerated errors match."""
42
- if not isinstance(other, EnumeratedError):
43
- return NotImplemented
44
- return (
45
- self.code == other.code
46
- and self.message == other.message
47
- and self.detail == other.detail
48
- and self.wrapping == other.wrapping
49
- )
50
-
51
-
52
- class CommunicationError(EnumeratedError):
53
- """An exception indicating an unknown communications error.
54
-
55
- This can either be used directly (by not specifying an error code, in which case
56
- it will get the base communication error code) or as an intermediate parent in which
57
- case you should specify the code with a super call.
58
- """
59
-
60
- def __init__(
61
- self,
62
- code: Optional[ErrorCodes] = None,
63
- message: Optional[str] = None,
64
- detail: Optional[Dict[str, str]] = None,
65
- wrapping: Optional[Sequence[EnumeratedError]] = None,
66
- ) -> None:
67
- """Build a CommunicationError."""
68
- if code and code not in code.of_category(
69
- ErrorCategories.HARDWARE_COMMUNICATION_ERROR
70
- ):
71
- log.error(
72
- f"Error {code.name} is inappropriate for a CommunicationError exception"
73
- )
74
- super().__init__(
75
- code or ErrorCodes.COMMUNICATION_ERROR, message, detail, wrapping
76
- )
77
-
78
-
79
- class RoboticsControlError(EnumeratedError):
80
- """An exception indicating an unknown robotics control error.
81
-
82
- This can either be used directly (by not specifying an error code, in which case
83
- it will get the base robotics control error code) or as an intermediate parent in which
84
- case you should specify the code with a super call.
85
- """
86
-
87
- def __init__(
88
- self,
89
- code: Optional[ErrorCodes] = None,
90
- message: Optional[str] = None,
91
- detail: Optional[Dict[str, str]] = None,
92
- wrapping: Optional[Sequence[EnumeratedError]] = None,
93
- ) -> None:
94
- """Build a RoboticsControlError."""
95
- if code and code not in code.of_category(
96
- ErrorCategories.ROBOTICS_CONTROL_ERROR
97
- ):
98
- log.error(
99
- f"Error {code.name} is inappropriate for a RoboticsControlError exception"
100
- )
101
-
102
- super().__init__(
103
- code or ErrorCodes.ROBOTICS_CONTROL_ERROR, message, detail, wrapping
104
- )
105
-
106
-
107
- class RoboticsInteractionError(EnumeratedError):
108
- """An exception indicating an unknown robotics interacion error.
109
-
110
- This can either be used directly (by not specifying an error code, in which case
111
- it will get the base robotics interaction error code) or as an intermediate parent in which
112
- case you should specify the code with a super call.
113
- """
114
-
115
- def __init__(
116
- self,
117
- code: Optional[ErrorCodes] = None,
118
- message: Optional[str] = None,
119
- detail: Optional[Dict[str, str]] = None,
120
- wrapping: Optional[Sequence[EnumeratedError]] = None,
121
- ) -> None:
122
- """Build a RoboticsInteractionError."""
123
- if code and code not in code.of_category(
124
- ErrorCategories.ROBOTICS_INTERACTION_ERROR
125
- ):
126
- log.error(
127
- f"Error {code.name} is inappropriate for a RoboticsInteractionError exception"
128
- )
129
-
130
- super().__init__(
131
- code or ErrorCodes.ROBOTICS_INTERACTION_ERROR, message, detail, wrapping
132
- )
133
-
134
-
135
- class GeneralError(EnumeratedError):
136
- """An exception indicating an unknown general error.
137
-
138
- This can either be used directly (by not specifying an error code, in which case
139
- it will get the base general error code) or as an intermediate parent in which
140
- case you should specify the code with a super call.
141
- """
142
-
143
- def __init__(
144
- self,
145
- code: Optional[ErrorCodes] = None,
146
- message: Optional[str] = None,
147
- detail: Optional[Dict[str, str]] = None,
148
- wrapping: Optional[Sequence[Union[EnumeratedError, BaseException]]] = None,
149
- ) -> None:
150
- """Build a GeneralError."""
151
- if code and code not in code.of_category(ErrorCategories.GENERAL_ERROR):
152
- log.error(
153
- f"Error {code.name} is inappropriate for a GeneralError exception"
154
- )
155
-
156
- def _wrapped_excs() -> Iterator[EnumeratedError]:
157
- if not wrapping:
158
- return
159
- for exc in wrapping:
160
- if isinstance(exc, EnumeratedError):
161
- yield exc
162
- else:
163
- yield PythonException(exc)
164
-
165
- super().__init__(
166
- code or ErrorCodes.GENERAL_ERROR, message, detail, list(_wrapped_excs())
167
- )
168
-
169
-
170
- def _exc_harvest_predicate(v: Any) -> bool:
171
- if inspect.isroutine(v):
172
- return False
173
- if inspect.ismethoddescriptor(v):
174
- return False
175
- # on python 3.11 and up we can check if things are method wrappers, which basic builtin
176
- # dunders like __add__ are, but until then we can't and also don't know this is real
177
- if sys.version_info.minor >= 11 and inspect.ismethodwrapper(v): # type: ignore[attr-defined]
178
- return False
179
- return True
180
-
181
-
182
- class PythonException(GeneralError):
183
- """An exception wrapping a base exception but with a GeneralError code and storing details."""
184
-
185
- def __init__(self, exc: BaseException) -> None:
186
- """Build a PythonException."""
187
-
188
- def _descend_exc_ctx(exc: BaseException) -> List[PythonException]:
189
- descendants: List[PythonException] = []
190
- if exc.__context__:
191
- descendants.append(PythonException(exc.__context__))
192
- if exc.__cause__:
193
- descendants.append(PythonException(exc.__cause__))
194
- return descendants
195
-
196
- base_details = {
197
- k: str(v)
198
- for k, v in inspect.getmembers(exc, _exc_harvest_predicate)
199
- if not k.startswith("_")
200
- }
201
- try:
202
- tb = exc.__traceback__
203
- except AttributeError:
204
- tb = None
205
-
206
- if tb:
207
- base_details["traceback"] = "\n".join(format_tb(tb))
208
- base_details["class"] = type(exc).__name__
209
-
210
- super().__init__(
211
- message="\n".join(format_exception_only(type(exc), exc)).strip(),
212
- detail=base_details,
213
- wrapping=_descend_exc_ctx(exc),
214
- )
215
-
216
-
217
- class RobotInUseError(CommunicationError):
218
- """An error indicating that an action cannot proceed because another is in progress."""
219
-
220
- def __init__(
221
- self,
222
- message: Optional[str] = None,
223
- detail: Optional[Dict[str, str]] = None,
224
- wrapping: Optional[Sequence[EnumeratedError]] = None,
225
- ) -> None:
226
- """Build a CanbusCommunicationError."""
227
- super().__init__(ErrorCodes.ROBOT_IN_USE, message, detail, wrapping)
228
-
229
-
230
- class CanbusCommunicationError(CommunicationError):
231
- """An error indicating a problem with canbus communication."""
232
-
233
- def __init__(
234
- self,
235
- message: Optional[str] = None,
236
- detail: Optional[Dict[str, str]] = None,
237
- wrapping: Optional[Sequence[EnumeratedError]] = None,
238
- ) -> None:
239
- """Build a CanbusCommunicationError."""
240
- super().__init__(
241
- ErrorCodes.CANBUS_COMMUNICATION_ERROR, message, detail, wrapping
242
- )
243
-
244
-
245
- class InternalUSBCommunicationError(CommunicationError):
246
- """An error indicating a problem with internal USB communication - e.g. with the rear panel."""
247
-
248
- def __init__(
249
- self,
250
- message: Optional[str] = None,
251
- detail: Optional[Dict[str, str]] = None,
252
- wrapping: Optional[Sequence[EnumeratedError]] = None,
253
- ) -> None:
254
- """Build an InternalUSBCommunicationError."""
255
- super().__init__(
256
- ErrorCodes.INTERNAL_USB_COMMUNICATION_ERROR, message, detail, wrapping
257
- )
258
-
259
-
260
- class ModuleCommunicationError(CommunicationError):
261
- """An error indicating a problem with module communication."""
262
-
263
- def __init__(
264
- self,
265
- message: Optional[str] = None,
266
- detail: Optional[Dict[str, str]] = None,
267
- wrapping: Optional[Sequence[EnumeratedError]] = None,
268
- ) -> None:
269
- """Build a CanbusCommunicationError."""
270
- super().__init__(
271
- ErrorCodes.CANBUS_COMMUNICATION_ERROR, message, detail, wrapping
272
- )
273
-
274
-
275
- class CommandTimedOutError(CommunicationError):
276
- """An error indicating that a command timed out."""
277
-
278
- def __init__(
279
- self,
280
- message: Optional[str] = None,
281
- detail: Optional[Dict[str, str]] = None,
282
- wrapping: Optional[Sequence[EnumeratedError]] = None,
283
- ) -> None:
284
- """Build a CommandTimedOutError."""
285
- super().__init__(ErrorCodes.COMMAND_TIMED_OUT, message, detail, wrapping)
286
-
287
-
288
- class FirmwareUpdateFailedError(CommunicationError):
289
- """An error indicating that a firmware update failed."""
290
-
291
- def __init__(
292
- self,
293
- message: Optional[str] = None,
294
- detail: Optional[Dict[str, str]] = None,
295
- wrapping: Optional[Sequence[EnumeratedError]] = None,
296
- ) -> None:
297
- """Build a FirmwareUpdateFailedError."""
298
- super().__init__(ErrorCodes.FIRMWARE_UPDATE_FAILED, message, detail, wrapping)
299
-
300
-
301
- class InternalMessageFormatError(CommunicationError):
302
- """An error indicating that an internal message was formatted incorrectly."""
303
-
304
- def __init__(
305
- self,
306
- message: Optional[str] = None,
307
- detail: Optional[Dict[str, str]] = None,
308
- wrapping: Optional[Sequence[EnumeratedError]] = None,
309
- ) -> None:
310
- """Build an InternalMesasgeFormatError."""
311
- super().__init__(
312
- ErrorCodes.INTERNAL_MESSAGE_FORMAT_ERROR, message, detail, wrapping
313
- )
314
-
315
-
316
- class CANBusConfigurationError(CommunicationError):
317
- """An error indicating a misconfiguration of the CANbus."""
318
-
319
- def __init__(
320
- self,
321
- message: Optional[str] = None,
322
- detail: Optional[Dict[str, str]] = None,
323
- wrapping: Optional[Sequence[EnumeratedError]] = None,
324
- ) -> None:
325
- """Build a CANBus Configuration Error."""
326
- super().__init__(
327
- ErrorCodes.CANBUS_CONFIGURATION_ERROR, message, detail, wrapping
328
- )
329
-
330
-
331
- class CANBusBusError(CommunicationError):
332
- """An error indicating a low-level bus error on the CANbus like an error frame."""
333
-
334
- def __init__(
335
- self,
336
- message: Optional[str] = None,
337
- detail: Optional[Dict[str, str]] = None,
338
- wrapping: Optional[Sequence[EnumeratedError]] = None,
339
- ) -> None:
340
- """Build a CANBus Bus Error."""
341
- super().__init__(ErrorCodes.CANBUS_BUS_ERROR, message, detail, wrapping)
342
-
343
-
344
- class MotionFailedError(RoboticsControlError):
345
- """An error indicating that a motion failed."""
346
-
347
- def __init__(
348
- self,
349
- message: Optional[str] = None,
350
- detail: Optional[Dict[str, str]] = None,
351
- wrapping: Optional[Sequence[EnumeratedError]] = None,
352
- ) -> None:
353
- """Build a MotionFailedError."""
354
- super().__init__(ErrorCodes.MOTION_FAILED, message, detail, wrapping)
355
-
356
-
357
- class HomingFailedError(RoboticsControlError):
358
- """An error indicating that a homing failed."""
359
-
360
- def __init__(
361
- self,
362
- message: Optional[str] = None,
363
- detail: Optional[Dict[str, str]] = None,
364
- wrapping: Optional[Sequence[EnumeratedError]] = None,
365
- ) -> None:
366
- """Build a HomingFailedError."""
367
- super().__init__(ErrorCodes.HOMING_FAILED, message, detail, wrapping)
368
-
369
-
370
- class StallOrCollisionDetectedError(RoboticsControlError):
371
- """An error indicating that a stall or collision occurred."""
372
-
373
- def __init__(
374
- self,
375
- message: Optional[str] = None,
376
- detail: Optional[Dict[str, str]] = None,
377
- wrapping: Optional[Sequence[EnumeratedError]] = None,
378
- ) -> None:
379
- """Build a StallOrCollisionDetectedError."""
380
- super().__init__(
381
- ErrorCodes.STALL_OR_COLLISION_DETECTED, message, detail, wrapping
382
- )
383
-
384
-
385
- class MotionPlanningFailureError(RoboticsControlError):
386
- """An error indicating that motion planning failed."""
387
-
388
- def __init__(
389
- self,
390
- message: Optional[str] = None,
391
- detail: Optional[Dict[str, str]] = None,
392
- wrapping: Optional[Sequence[EnumeratedError]] = None,
393
- ) -> None:
394
- """Build a MotionPlanningFailureError."""
395
- super().__init__(ErrorCodes.MOTION_PLANNING_FAILURE, message, detail, wrapping)
396
-
397
-
398
- class PositionEstimationInvalidError(RoboticsControlError):
399
- """An error indicating that a command failed because position estimation was invalid."""
400
-
401
- def __init__(
402
- self,
403
- message: Optional[str] = None,
404
- detail: Optional[Dict[str, str]] = None,
405
- wrapping: Optional[Sequence[EnumeratedError]] = None,
406
- ) -> None:
407
- """Build a PositionEstimationFailedError."""
408
- super().__init__(
409
- ErrorCodes.POSITION_ESTIMATION_INVALID, message, detail, wrapping
410
- )
411
-
412
-
413
- class MoveConditionNotMetError(RoboticsControlError):
414
- """An error indicating that a move completed without its condition being met."""
415
-
416
- def __init__(
417
- self,
418
- message: Optional[str] = None,
419
- detail: Optional[Dict[str, str]] = None,
420
- wrapping: Optional[Sequence[EnumeratedError]] = None,
421
- ) -> None:
422
- """Build a MoveConditionNotMetError."""
423
- super().__init__(
424
- ErrorCodes.MOVE_CONDITION_NOT_MET,
425
- message or "Move completed without its complete condition being met",
426
- detail,
427
- wrapping,
428
- )
429
-
430
-
431
- class CalibrationStructureNotFoundError(RoboticsControlError):
432
- """An error indicating that a calibration square was not able to be found."""
433
-
434
- def __init__(
435
- self,
436
- structure_height: float,
437
- lower_limit: float,
438
- detail: Optional[Dict[str, str]] = None,
439
- wrapping: Optional[Sequence[EnumeratedError]] = None,
440
- ) -> None:
441
- """Build a CalibrationStructureNotFoundError."""
442
- super().__init__(
443
- ErrorCodes.CALIBRATION_STRUCTURE_NOT_FOUND,
444
- f"Structure height at z={structure_height}mm beyond lower limit: {lower_limit}.",
445
- detail,
446
- wrapping,
447
- )
448
-
449
-
450
- class EdgeNotFoundError(RoboticsControlError):
451
- """An error indicating that a calibration square edge was not able to be found."""
452
-
453
- def __init__(
454
- self,
455
- edge_name: str,
456
- stride: float,
457
- detail: Optional[Dict[str, str]] = None,
458
- wrapping: Optional[Sequence[EnumeratedError]] = None,
459
- ) -> None:
460
- """Build a EdgeNotFoundError."""
461
- super().__init__(
462
- ErrorCodes.EDGE_NOT_FOUND,
463
- f"Edge {edge_name} could not be verified at {stride} mm resolution.",
464
- detail,
465
- wrapping,
466
- )
467
-
468
-
469
- class EarlyCapacitiveSenseTrigger(RoboticsControlError):
470
- """An error indicating that a capacitive probe triggered too early."""
471
-
472
- def __init__(
473
- self,
474
- found: float,
475
- nominal: float,
476
- detail: Optional[Dict[str, str]] = None,
477
- wrapping: Optional[Sequence[EnumeratedError]] = None,
478
- ) -> None:
479
- """Build a EarlyCapacitiveSenseTrigger."""
480
- super().__init__(
481
- ErrorCodes.EARLY_CAPACITIVE_SENSE_TRIGGER,
482
- f"Calibration triggered early at z={found}mm, expected {nominal}",
483
- detail,
484
- wrapping,
485
- )
486
-
487
-
488
- class InaccurateNonContactSweepError(RoboticsControlError):
489
- """An error indicating that a capacitive sweep was inaccurate."""
490
-
491
- def __init__(
492
- self,
493
- found: float,
494
- nominal: float,
495
- detail: Optional[Dict[str, str]] = None,
496
- wrapping: Optional[Sequence[EnumeratedError]] = None,
497
- ) -> None:
498
- """Build a InaccurateNonContactSweepError."""
499
- msg = (
500
- f"Calibration detected a slot width of {found:.3f}mm, "
501
- f"which is too far from the design width of {nominal:.3f}mm"
502
- )
503
- super().__init__(
504
- ErrorCodes.INACCURATE_NON_CONTACT_SWEEP,
505
- msg,
506
- detail,
507
- wrapping,
508
- )
509
-
510
-
511
- class MisalignedGantryError(RoboticsControlError):
512
- """An error indicating that the robot's gantry and deck are misaligned."""
513
-
514
- def __init__(
515
- self,
516
- detail: Optional[Dict[str, str]] = None,
517
- wrapping: Optional[Sequence[EnumeratedError]] = None,
518
- ) -> None:
519
- """Build a MisalignedGantryError."""
520
- msg = "This machine is misaligned and requires maintenance."
521
- if detail:
522
- msg += str(detail)
523
- super().__init__(
524
- ErrorCodes.MISALIGNED_GANTRY,
525
- msg,
526
- detail,
527
- wrapping,
528
- )
529
-
530
-
531
- class UnmatchedTipPresenceStates(RoboticsControlError):
532
- """An error indicating that a tip presence check resulted in two differing responses."""
533
-
534
- def __init__(
535
- self,
536
- states: Dict[int, int],
537
- detail: Optional[Dict[str, str]] = None,
538
- wrapping: Optional[Sequence[EnumeratedError]] = None,
539
- ) -> None:
540
- """Build an UnmatchedTipPresenceStatesError."""
541
- format_tip_state = {0: "not detected", 1: "detected"}
542
- msg = (
543
- "Received two differing tip presence statuses:"
544
- "\nRear Sensor tips"
545
- + format_tip_state[states[0]]
546
- + "\nFront Sensor tips"
547
- + format_tip_state[states[1]]
548
- )
549
- if detail:
550
- msg += str(detail)
551
- super().__init__(
552
- ErrorCodes.UNMATCHED_TIP_PRESENCE_STATES,
553
- msg,
554
- detail,
555
- wrapping,
556
- )
557
-
558
-
559
- class PositionUnknownError(RoboticsControlError):
560
- """An error indicating that the robot's position is unknown."""
561
-
562
- def __init__(
563
- self,
564
- message: Optional[str] = None,
565
- detail: Optional[Dict[str, str]] = None,
566
- wrapping: Optional[Sequence[EnumeratedError]] = None,
567
- ) -> None:
568
- """Build a PositionUnknownError."""
569
- super().__init__(ErrorCodes.POSITION_UNKNOWN, message, detail, wrapping)
570
-
571
-
572
- class ExecutionCancelledError(RoboticsControlError):
573
- """An error indicating that the robot's execution manager has been cancelled."""
574
-
575
- def __init__(
576
- self,
577
- message: Optional[str] = None,
578
- detail: Optional[Dict[str, str]] = None,
579
- wrapping: Optional[Sequence[EnumeratedError]] = None,
580
- ) -> None:
581
- """Build a ExecutionCancelledError."""
582
- super().__init__(ErrorCodes.EXECUTION_CANCELLED, message, detail, wrapping)
583
-
584
-
585
- class LabwareDroppedError(RoboticsInteractionError):
586
- """An error indicating that the gripper dropped labware it was holding."""
587
-
588
- def __init__(
589
- self,
590
- message: Optional[str] = None,
591
- detail: Optional[Dict[str, str]] = None,
592
- wrapping: Optional[Sequence[EnumeratedError]] = None,
593
- ) -> None:
594
- """Build a LabwareDroppedError."""
595
- super().__init__(ErrorCodes.LABWARE_DROPPED, message, detail, wrapping)
596
-
597
-
598
- class TipPickupFailedError(RoboticsInteractionError):
599
- """An error indicating that a pipette failed to pick up a tip."""
600
-
601
- def __init__(
602
- self,
603
- message: Optional[str] = None,
604
- detail: Optional[Dict[str, str]] = None,
605
- wrapping: Optional[Sequence[EnumeratedError]] = None,
606
- ) -> None:
607
- """Build a TipPickupFailedError."""
608
- super().__init__(ErrorCodes.TIP_PICKUP_FAILED, message, detail, wrapping)
609
-
610
-
611
- class TipDropFailedError(RoboticsInteractionError):
612
- """An error indicating that a pipette failed to drop a tip."""
613
-
614
- def __init__(
615
- self,
616
- message: Optional[str] = None,
617
- detail: Optional[Dict[str, str]] = None,
618
- wrapping: Optional[Sequence[EnumeratedError]] = None,
619
- ) -> None:
620
- """Build a TipPickupFailedError."""
621
- super().__init__(ErrorCodes.TIP_DROP_FAILED, message, detail, wrapping)
622
-
623
-
624
- class UnexpectedTipRemovalError(RoboticsInteractionError):
625
- """An error indicating that a pipette did not have a tip when it should (aka it fell off)."""
626
-
627
- def __init__(
628
- self,
629
- action: str,
630
- pipette_name: str,
631
- mount: str,
632
- detail: Optional[Dict[str, str]] = None,
633
- wrapping: Optional[Sequence[EnumeratedError]] = None,
634
- ) -> None:
635
- """Build an UnexpectedTipRemovalError."""
636
- checked_detail: Dict[str, Any] = detail or {}
637
- checked_detail["pipette_name"] = pipette_name
638
- checked_detail["mount"] = mount
639
- message = f"Cannot perform {action} without a tip attached."
640
- super().__init__(
641
- ErrorCodes.UNEXPECTED_TIP_REMOVAL, message, checked_detail, wrapping
642
- )
643
-
644
-
645
- class UnexpectedTipAttachError(RoboticsInteractionError):
646
- """An error indicating that a pipette had a tip when it shouldn't."""
647
-
648
- def __init__(
649
- self,
650
- action: str,
651
- pipette_name: str,
652
- mount: str,
653
- message: Optional[str] = None,
654
- detail: Optional[Dict[str, str]] = None,
655
- wrapping: Optional[Sequence[EnumeratedError]] = None,
656
- ) -> None:
657
- """Build an UnexpectedTipAttachError."""
658
- checked_detail: Dict[str, Any] = detail or {}
659
- checked_detail["pipette_name"] = pipette_name
660
- checked_detail["mount"] = mount
661
- message = f"Cannot perform {action} with a tip already attached."
662
- super().__init__(ErrorCodes.UNEXPECTED_TIP_ATTACH, message, detail, wrapping)
663
-
664
-
665
- class FirmwareUpdateRequiredError(RoboticsInteractionError):
666
- """An error indicating that a firmware update is required."""
667
-
668
- def __init__(
669
- self,
670
- action: str,
671
- subsystems_to_update: List[Any],
672
- message: Optional[str] = None,
673
- detail: Optional[Dict[str, str]] = None,
674
- wrapping: Optional[Sequence[EnumeratedError]] = None,
675
- ) -> None:
676
- """Build a FirmwareUpdateRequiredError."""
677
- checked_detail: Dict[str, Any] = detail or {}
678
- checked_detail["identifier"] = action
679
- checked_detail["subsystems_to_update"] = subsystems_to_update
680
- message = f"Cannot perform {action} until {subsystems_to_update} are updated."
681
- super().__init__(ErrorCodes.FIRMWARE_UPDATE_REQUIRED, message, detail, wrapping)
682
-
683
-
684
- class PipetteOverpressureError(RoboticsInteractionError):
685
- """An error indicating that a pipette experienced an overpressure event, likely because of a clog."""
686
-
687
- def __init__(
688
- self,
689
- message: Optional[str] = None,
690
- detail: Optional[Dict[str, str]] = None,
691
- wrapping: Optional[Sequence[EnumeratedError]] = None,
692
- ) -> None:
693
- """Build an PipetteOverpressureError."""
694
- super().__init__(ErrorCodes.PIPETTE_OVERPRESSURE, message, detail, wrapping)
695
-
696
-
697
- class EStopActivatedError(RoboticsInteractionError):
698
- """An error indicating that the E-stop was activated."""
699
-
700
- def __init__(
701
- self,
702
- message: Optional[str] = None,
703
- detail: Optional[Dict[str, str]] = None,
704
- wrapping: Optional[Sequence[EnumeratedError]] = None,
705
- ) -> None:
706
- """Build an EStopActivatedError."""
707
- super().__init__(ErrorCodes.E_STOP_ACTIVATED, message, detail, wrapping)
708
-
709
-
710
- class EStopNotPresentError(RoboticsInteractionError):
711
- """An error indicating that the E-stop is not present."""
712
-
713
- def __init__(
714
- self,
715
- message: Optional[str] = None,
716
- detail: Optional[Dict[str, str]] = None,
717
- wrapping: Optional[Sequence[EnumeratedError]] = None,
718
- ) -> None:
719
- """Build an EStopNotPresentError."""
720
- super().__init__(ErrorCodes.E_STOP_NOT_PRESENT, message, detail, wrapping)
721
-
722
-
723
- class PipetteNotPresentError(RoboticsInteractionError):
724
- """An error indicating that the specified pipette is not present."""
725
-
726
- def __init__(
727
- self,
728
- message: Optional[str] = None,
729
- detail: Optional[Dict[str, str]] = None,
730
- wrapping: Optional[Sequence[EnumeratedError]] = None,
731
- ) -> None:
732
- """Build an PipetteNotPresentError."""
733
- super().__init__(ErrorCodes.PIPETTE_NOT_PRESENT, message, detail, wrapping)
734
-
735
-
736
- class GripperNotPresentError(RoboticsInteractionError):
737
- """An error indicating that the specified gripper is not present."""
738
-
739
- def __init__(
740
- self,
741
- message: Optional[str] = None,
742
- detail: Optional[Dict[str, str]] = None,
743
- wrapping: Optional[Sequence[EnumeratedError]] = None,
744
- ) -> None:
745
- """Build a GripperNotPresentError."""
746
- super().__init__(ErrorCodes.GRIPPER_NOT_PRESENT, message, detail, wrapping)
747
-
748
-
749
- class InvalidActuator(RoboticsInteractionError):
750
- """An error indicating that a specified actuator is not valid."""
751
-
752
- def __init__(
753
- self,
754
- message: Optional[str] = None,
755
- detail: Optional[Dict[str, str]] = None,
756
- wrapping: Optional[Sequence[EnumeratedError]] = None,
757
- ) -> None:
758
- """Build an InvalidActuator."""
759
- super().__init__(ErrorCodes.INVALID_ACTUATOR, message, detail, wrapping)
760
-
761
-
762
- class ModuleNotPresent(RoboticsInteractionError):
763
- """An error indicating that a specific module was not present."""
764
-
765
- def __init__(
766
- self,
767
- identifier: str,
768
- message: Optional[str] = None,
769
- detail: Optional[Dict[str, str]] = None,
770
- wrapping: Optional[Sequence[EnumeratedError]] = None,
771
- ) -> None:
772
- """Build a ModuleNotPresentError."""
773
- checked_detail: Dict[str, Any] = detail or {}
774
- checked_detail["identifier"] = identifier
775
- checked_message = message or f"Module {identifier} is not present"
776
- super().__init__(
777
- ErrorCodes.MODULE_NOT_PRESENT, checked_message, checked_detail, wrapping
778
- )
779
-
780
-
781
- class InvalidInstrumentData(RoboticsInteractionError):
782
- """An error indicating that instrument data is invalid."""
783
-
784
- def __init__(
785
- self,
786
- message: Optional[str] = None,
787
- detail: Optional[Dict[str, str]] = None,
788
- wrapping: Optional[Sequence[EnumeratedError]] = None,
789
- ) -> None:
790
- """Build an InvalidInstrumentData."""
791
- super().__init__(ErrorCodes.INVALID_INSTRUMENT_DATA, message, detail, wrapping)
792
-
793
-
794
- class InvalidLiquidClassName(RoboticsInteractionError):
795
- """An error indicating that a liquid class name does not exist on a pipette."""
796
-
797
- def __init__(
798
- self,
799
- message: Optional[str] = None,
800
- detail: Optional[Dict[str, str]] = None,
801
- wrapping: Optional[Sequence[EnumeratedError]] = None,
802
- ) -> None:
803
- """Build an InvalidLiquidClassName."""
804
- super().__init__(
805
- ErrorCodes.INVALID_LIQUID_CLASS_NAME, message, detail, wrapping
806
- )
807
-
808
-
809
- class TipDetectorNotFound(RoboticsInteractionError):
810
- """An error indicating that a tip detector has not been created for a pipette."""
811
-
812
- def __init__(
813
- self,
814
- message: Optional[str] = None,
815
- detail: Optional[Dict[str, str]] = None,
816
- wrapping: Optional[Sequence[EnumeratedError]] = None,
817
- ) -> None:
818
- """Build a TipDetectorNotFound."""
819
- super().__init__(ErrorCodes.TIP_DETECTOR_NOT_FOUND, message, detail, wrapping)
820
-
821
-
822
- class APIRemoved(GeneralError):
823
- """An error indicating that a specific API is no longer available."""
824
-
825
- def __init__(
826
- self,
827
- api_element: str,
828
- since_version: str,
829
- message: Optional[str] = None,
830
- detail: Optional[Dict[str, str]] = None,
831
- wrapping: Optional[Sequence[EnumeratedError]] = None,
832
- ) -> None:
833
- """Build an APIRemoved error."""
834
- checked_detail: Dict[str, Any] = detail or {}
835
- checked_detail["identifier"] = api_element
836
- checked_detail["since_version"] = since_version
837
- checked_message = (
838
- message
839
- or f"{api_element} is no longer available since version {since_version}."
840
- )
841
- super().__init__(
842
- ErrorCodes.API_REMOVED, checked_message, checked_detail, wrapping
843
- )
844
-
845
-
846
- class CommandPreconditionViolated(GeneralError):
847
- """An error indicating that a command was issued in a robot state incompatible with it."""
848
-
849
- def __init__(
850
- self,
851
- message: Optional[str] = None,
852
- detail: Optional[Dict[str, str]] = None,
853
- wrapping: Optional[Sequence[EnumeratedError]] = None,
854
- ) -> None:
855
- """Build a CommandPreconditionViolated instance."""
856
- super().__init__(
857
- ErrorCodes.COMMAND_PRECONDITION_VIOLATED, message, detail, wrapping
858
- )
859
-
860
-
861
- class CommandParameterLimitViolated(GeneralError):
862
- """An error indicating that a command's parameter limit was violated."""
863
-
864
- def __init__(
865
- self,
866
- command_name: str,
867
- parameter_name: str,
868
- limit_statement: str,
869
- actual_value: str,
870
- wrapping: Optional[Sequence[Union[EnumeratedError, BaseException]]] = None,
871
- ) -> None:
872
- """Build a CommandParameterLimitViolated error."""
873
- wrapping_checked = wrapping or []
874
- super().__init__(
875
- ErrorCodes.COMMAND_PARAMETER_LIMIT_VIOLATED,
876
- f"The parameter {parameter_name} of {command_name} must be {limit_statement} but is {actual_value}",
877
- detail={
878
- "command": command_name,
879
- "argument": parameter_name,
880
- "limit": limit_statement,
881
- "value": actual_value,
882
- },
883
- wrapping=[
884
- PythonException(e) if isinstance(e, BaseException) else e
885
- for e in wrapping_checked
886
- ],
887
- )
888
-
889
-
890
- class UnsupportedHardwareCommand(GeneralError):
891
- """An error indicating that a command being executed is not supported by the hardware."""
892
-
893
- def __init__(
894
- self,
895
- message: Optional[str] = None,
896
- detail: Optional[Dict[str, str]] = None,
897
- wrapping: Optional[Sequence[EnumeratedError]] = None,
898
- ) -> None:
899
- """Build an UnsupportedHardwareCommand."""
900
- super().__init__(
901
- ErrorCodes.NOT_SUPPORTED_ON_ROBOT_TYPE, message, detail, wrapping
902
- )
903
-
904
-
905
- class InvalidProtocolData(GeneralError):
906
- """An error indicating that some protocol data is invalid."""
907
-
908
- def __init__(
909
- self,
910
- message: Optional[str] = None,
911
- detail: Optional[Dict[str, str]] = None,
912
- wrapping: Optional[Sequence[EnumeratedError]] = None,
913
- ) -> None:
914
- """Build an InvalidProtocolData."""
915
- super().__init__(ErrorCodes.INVALID_PROTOCOL_DATA, message, detail, wrapping)