Skip to content

Commit f61bc3a

Browse files
authored
feat(api): remove the heater shaker low temp limit (#19076)
This is a helpful limit to prevent people from commanding an unachievable temperature; but sometimes people have nice ACs in their labs. Remove the limit. Closes EXEC-1654 ## testing - on api 2.25 you should be able to command 30C
1 parent c0022e9 commit f61bc3a

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed

api/src/opentrons/protocol_api/module_contexts.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,11 @@ def set_and_wait_for_temperature(self, celsius: float) -> None:
894894
895895
No other protocol commands will execute while waiting for the temperature.
896896
897-
:param celsius: A value between 27 and 95, representing the target temperature in °C.
897+
.. versionchanged:: 2.25
898+
Removed the minimum temperature limit of 37 °C. Note that temperatures under ambient are
899+
not achievable.
900+
901+
:param celsius: A value under 95, representing the target temperature in °C.
898902
Values are automatically truncated to two decimal places,
899903
and the Heater-Shaker module has a temperature accuracy of ±0.5 °C.
900904
"""
@@ -912,11 +916,17 @@ def set_target_temperature(self, celsius: float) -> None:
912916
Use :py:meth:`~.HeaterShakerContext.wait_for_temperature` to delay
913917
protocol execution.
914918
915-
:param celsius: A value between 27 and 95, representing the target temperature in °C.
919+
.. versionchanged:: 2.25
920+
Removed the minimum temperature limit of 37 °C. Note that temperatures under ambient are
921+
not achievable.
922+
923+
:param celsius: A value under 95, representing the target temperature in °C.
916924
Values are automatically truncated to two decimal places,
917925
and the Heater-Shaker module has a temperature accuracy of ±0.5 °C.
918926
"""
919-
validated_temp = validate_heater_shaker_temperature(celsius=celsius)
927+
validated_temp = validate_heater_shaker_temperature(
928+
celsius=celsius, api_version=self.api_version
929+
)
920930
self._core.set_target_temperature(celsius=validated_temp)
921931

922932
@requires_version(2, 13)

api/src/opentrons/protocol_api/module_validation_and_errors.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
"""Contains module command validation functions and module errors for heater-shaker."""
22

3+
from opentrons.protocols.api_support.types import APIVersion
4+
35
# TODO (spp, 2022-03-22): Move these values to heater-shaker module definition.
46
HEATER_SHAKER_TEMPERATURE_MIN = 37
57
HEATER_SHAKER_TEMPERATURE_MAX = 95
68
HEATER_SHAKER_SPEED_MIN = 200
79
HEATER_SHAKER_SPEED_MAX = 3000
10+
HEATER_SHAKER_TEMPERATURE_MIN_REMOVED_IN = APIVersion(2, 25)
811

912

1013
class InvalidTargetTemperatureError(ValueError):
@@ -15,8 +18,18 @@ class InvalidTargetSpeedError(ValueError):
1518
"""An error raised when attempting to set an invalid target speed."""
1619

1720

18-
def validate_heater_shaker_temperature(celsius: float) -> float:
19-
"""Verify that the target temperature being set is valid for heater-shaker."""
21+
def _validate_hs_temp_nomin(celsius: float) -> float:
22+
if celsius <= HEATER_SHAKER_TEMPERATURE_MAX:
23+
return celsius
24+
else:
25+
raise InvalidTargetTemperatureError(
26+
f"Cannot set Heater-Shaker to {celsius} °C."
27+
f" The maximum temperature for the Heater-Shaker is"
28+
f"{HEATER_SHAKER_TEMPERATURE_MAX} °C."
29+
)
30+
31+
32+
def _validate_hs_temp_min(celsius: float) -> float:
2033
if HEATER_SHAKER_TEMPERATURE_MIN <= celsius <= HEATER_SHAKER_TEMPERATURE_MAX:
2134
return celsius
2235
else:
@@ -27,6 +40,16 @@ def validate_heater_shaker_temperature(celsius: float) -> float:
2740
)
2841

2942

43+
def validate_heater_shaker_temperature(
44+
celsius: float, api_version: APIVersion
45+
) -> float:
46+
"""Verify that the target temperature being set is valid for heater-shaker."""
47+
if api_version < HEATER_SHAKER_TEMPERATURE_MIN_REMOVED_IN:
48+
return _validate_hs_temp_min(celsius)
49+
else:
50+
return _validate_hs_temp_nomin(celsius)
51+
52+
3053
def validate_heater_shaker_speed(rpm: int) -> int:
3154
"""Verify that the target speed is valid for heater-shaker"""
3255
if HEATER_SHAKER_SPEED_MIN <= rpm <= HEATER_SHAKER_SPEED_MAX:

api/tests/opentrons/protocol_api_old/test_module_validation_and_errors.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22

3+
from opentrons.protocols.api_support.types import APIVersion
34
from opentrons.protocol_api.module_validation_and_errors import (
45
validate_heater_shaker_temperature,
56
validate_heater_shaker_speed,
@@ -11,17 +12,37 @@
1112
@pytest.mark.parametrize("valid_celsius_value", [37.0, 37.1, 50, 94.99, 95])
1213
def test_validate_heater_shaker_temperature(valid_celsius_value: float) -> None:
1314
"""It should return the validated temperature value."""
14-
validated = validate_heater_shaker_temperature(celsius=valid_celsius_value)
15+
validated = validate_heater_shaker_temperature(
16+
celsius=valid_celsius_value, api_version=APIVersion(2, 25)
17+
)
1518
assert validated == valid_celsius_value
1619

1720

1821
@pytest.mark.parametrize("invalid_celsius_value", [-1, 0, 36.99, 95.01])
19-
def test_validate_heater_shaker_temperature_raises(
22+
def test_validate_heater_shaker_temperature_raises_under_api_225(
2023
invalid_celsius_value: float,
2124
) -> None:
2225
"""It should raise an error for invalid temperature values."""
2326
with pytest.raises(InvalidTargetTemperatureError):
24-
validate_heater_shaker_temperature(celsius=invalid_celsius_value)
27+
validate_heater_shaker_temperature(
28+
celsius=invalid_celsius_value, api_version=APIVersion(2, 24)
29+
)
30+
31+
32+
@pytest.mark.parametrize("invalid_celsius_value", [95.01])
33+
def test_validate_heater_shaker_temperature_raises_over_api_225(
34+
invalid_celsius_value: float,
35+
) -> None:
36+
"""It should raise an error for invalid temperature values."""
37+
with pytest.raises(InvalidTargetTemperatureError):
38+
validate_heater_shaker_temperature(
39+
celsius=invalid_celsius_value, api_version=APIVersion(2, 25)
40+
)
41+
42+
43+
def test_validate_heater_shaker_temperature_passes_low_temp_over_api_225() -> None:
44+
"""It should not raise an error for values under 37."""
45+
assert validate_heater_shaker_temperature(celsius=22, api_version=APIVersion(2, 25))
2546

2647

2748
@pytest.mark.parametrize("valid_rpm_value", [200, 201, 1000, 2999, 3000])

0 commit comments

Comments
 (0)