Skip to content

Commit ad28f29

Browse files
authored
fix(api): SetShakeSpeed should set heatershaker state is_plate_shaking to true (#20024)
# Overview Adds `SetShakeSpeed` to heatershaker state updates Protocol analysis will now raise an error if you use `set_shake_speed` and then try to open the labware latch without deactivating the shaker first. ## Test Plan and Hands on Testing Simulated the protocol attached in the ticket, and error was raised `ProtocolCommandFailedError [line 491]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): CannotPerformModuleAction: Heater-Shaker cannot open its labware latch while it is shaking.` <img width="921" height="488" alt="Screenshot 2025-11-04 at 12 20 44 PM" src="https://github.com/user-attachments/assets/0898ca36-b09d-4b0b-b239-f5e43659e917" /> ## Risk assessment low Closes RQA-4814
1 parent 387e24a commit ad28f29

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

api/src/opentrons/protocol_engine/state/modules.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ def _handle_command(self, command: Command) -> None:
267267
heater_shaker.SetTargetTemperatureResult,
268268
heater_shaker.DeactivateHeaterResult,
269269
heater_shaker.SetAndWaitForShakeSpeedResult,
270+
heater_shaker.SetShakeSpeedResult,
270271
heater_shaker.DeactivateShakerResult,
271272
heater_shaker.OpenLabwareLatchResult,
272273
heater_shaker.CloseLabwareLatchResult,
@@ -430,6 +431,7 @@ def _handle_heater_shaker_commands(
430431
heater_shaker.SetTargetTemperature,
431432
heater_shaker.DeactivateHeater,
432433
heater_shaker.SetAndWaitForShakeSpeed,
434+
heater_shaker.SetShakeSpeed,
433435
heater_shaker.DeactivateShaker,
434436
heater_shaker.OpenLabwareLatch,
435437
heater_shaker.CloseLabwareLatch,
@@ -465,6 +467,13 @@ def _handle_heater_shaker_commands(
465467
is_plate_shaking=True,
466468
plate_target_temperature=prev_state.plate_target_temperature,
467469
)
470+
elif isinstance(command.result, heater_shaker.SetShakeSpeedResult):
471+
self._state.substate_by_module_id[module_id] = HeaterShakerModuleSubState(
472+
module_id=HeaterShakerModuleId(module_id),
473+
labware_latch_status=prev_state.labware_latch_status,
474+
is_plate_shaking=True,
475+
plate_target_temperature=prev_state.plate_target_temperature,
476+
)
468477
elif isinstance(command.result, heater_shaker.DeactivateShakerResult):
469478
self._state.substate_by_module_id[module_id] = HeaterShakerModuleSubState(
470479
module_id=HeaterShakerModuleId(module_id),

api/tests/opentrons/protocol_engine/state/test_module_store_old.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,15 @@ def test_handle_hs_shake_commands(heater_shaker_v1_def: ModuleDefinition) -> Non
486486
params=hs_commands.SetAndWaitForShakeSpeedParams(moduleId="module-id", rpm=111),
487487
result=hs_commands.SetAndWaitForShakeSpeedResult(pipetteRetracted=False),
488488
)
489+
start_set_shake_cmd = hs_commands.SetShakeSpeed.model_construct( # type: ignore[call-arg]
490+
params=hs_commands.SetShakeSpeedParams(moduleId="module-id", rpm=111),
491+
result=hs_commands.SetShakeSpeedResult(pipetteRetracted=False, taskId="taskId"),
492+
)
489493
deactivate_cmd = hs_commands.DeactivateShaker.model_construct( # type: ignore[call-arg]
490494
params=hs_commands.DeactivateShakerParams(moduleId="module-id"),
491495
result=hs_commands.DeactivateShakerResult(),
492496
)
497+
493498
subject = ModuleStore(
494499
config=_OT2_STANDARD_CONFIG,
495500
deck_fixed_labware=[],
@@ -516,6 +521,15 @@ def test_handle_hs_shake_commands(heater_shaker_v1_def: ModuleDefinition) -> Non
516521
plate_target_temperature=None,
517522
)
518523
}
524+
subject.handle_action(actions.SucceedCommandAction(command=start_set_shake_cmd))
525+
assert subject.state.substate_by_module_id == {
526+
"module-id": HeaterShakerModuleSubState(
527+
module_id=HeaterShakerModuleId("module-id"),
528+
labware_latch_status=HeaterShakerLatchStatus.UNKNOWN,
529+
is_plate_shaking=True,
530+
plate_target_temperature=None,
531+
)
532+
}
519533
subject.handle_action(actions.SucceedCommandAction(command=deactivate_cmd))
520534
assert subject.state.substate_by_module_id == {
521535
"module-id": HeaterShakerModuleSubState(

0 commit comments

Comments
 (0)