| name | opentrons-temperature-module |
| description | Opentrons Temperature Module - precise heating and cooling (4-95°C) for sample storage, enzyme reactions, and temperature-sensitive protocols with aluminum block adapters for plates, tubes, and PCR strips |
| allowed-tools | ["*"] |
Opentrons Temperature Module
Overview
The Opentrons Temperature Module provides precise temperature control (4-95°C) for maintaining samples at specific temperatures during automated protocols. Ideal for keeping reagents cold, pre-warming reaction components, temperature-sensitive incubations, and any workflow requiring stable thermal conditions without mixing.
Core value: Eliminate ice buckets and water baths. Maintain precise, reproducible temperatures on-deck for reagents, samples, and reaction components throughout your protocol.
When to Use
Use the Temperature Module skill when:
- Keeping reagents cold during protocol (e.g., enzymes at 4°C)
- Pre-warming reaction components (e.g., buffers at 37°C)
- Maintaining samples at specific temperatures
- Temperature-sensitive enzyme reactions without mixing
- Cooling samples after thermal processing
- Any protocol requiring stable temperature control (4-95°C)
Don't use when:
- Need mixing/shaking during temperature control (use Heater-Shaker Module)
- Require PCR thermal cycling (use Thermocycler Module)
- Temperature outside 4-95°C range
- Precise temperature ramping or cycling needed
Quick Reference
| Operation | Method | Key Parameters |
|---|
| Load module | protocol.load_module() | "temperature module gen2", location |
| Set temperature | set_temperature() | celsius (4-95) |
| Get current temperature | .temperature | Read-only property |
| Check status | .status | Returns "holding at target" or "idle" |
| Deactivate | deactivate() | - |
Platform Compatibility
Both Opentrons Flex and OT-2
Module Generations
- GEN1 - Original temperature module
- GEN2 - Improved cooling performance, better isolation (recommended)
Key GEN2 improvements:
- Plastic insulation around plate
- Shrouds for aluminum blocks
- Better cooling when sharing deck with running Thermocycler
- Same API as GEN1
Loading the Module
from opentrons import protocol_api
metadata = {'apiLevel': '2.19'}
def run(protocol: protocol_api.ProtocolContext):
temp_mod = protocol.load_module("temperature module gen2", "D1")
cold_plate = temp_mod.load_labware("opentrons_96_aluminumblock_generic_pcr_strip_200ul")
Module versions:
"temperature module gen2" - GEN2 (recommended)
"temperatureModuleV1" - GEN1 (legacy)
Deck slot: Any compatible slot (Flex: A1-D3, OT-2: 1-11)
Loading Labware
Standalone Adapters (API 2.15+)
Recommended approach - Load adapter first, then labware:
temp_block = temp_mod.load_adapter("opentrons_96_well_aluminum_block")
sample_plate = temp_block.load_labware("opentrons_96_wellplate_200ul_pcr_full_skirt")
Available adapters:
| Adapter Name | Compatible Labware |
|---|
opentrons_96_well_aluminum_block | 96-well plates, PCR plates |
opentrons_aluminum_flat_bottom_plate | Flat-bottom plates |
opentrons_96_deep_well_temp_mod_adapter | Deep-well plates |
Block-and-Tube Combinations
For tube racks with aluminum blocks:
tubes_nest = temp_mod.load_labware("opentrons_24_aluminumblock_nest_1.5ml_snapcap")
tubes_generic = temp_mod.load_labware("opentrons_24_aluminumblock_generic_2ml_screwcap")
Legacy Block-and-Plate Combinations
plate_combo = temp_mod.load_labware("opentrons_96_aluminumblock_biorad_wellplate_200ul")
Recommendation: Use standalone adapters (API 2.15+) for better flexibility.
Temperature Control
Setting Temperature
temp_mod.set_temperature(celsius=4)
pipette.transfer(100, cold_reagent, dest_plate.wells())
Temperature range: 4-95°C (1°C resolution)
Behavior: Protocol execution blocks (waits) until target temperature is reached.
Temperature Status
current_temp = temp_mod.temperature
protocol.comment(f"Module at {current_temp}°C")
status = temp_mod.status
if status == "holding at target":
protocol.comment("Temperature stable, proceeding")
Deactivating
temp_mod.deactivate()
Important: Module does not automatically deactivate at protocol end. Must be manually turned off via Opentrons App if protocol completes or is cancelled.
Common Patterns
Keeping Reagents Cold
temp_mod = protocol.load_module("temperature module gen2", "D1")
reagent_block = temp_mod.load_adapter("opentrons_24_aluminumblock_nest_1.5ml_snapcap")
temp_mod.set_temperature(4)
pipette.transfer(10, reagent_block["A1"], dest_plate.wells())
temp_mod.deactivate()
Pre-Warming Reaction Components
temp_mod = protocol.load_module("temperature module gen2", "C2")
warm_block = temp_mod.load_adapter("opentrons_96_well_aluminum_block")
warm_plate = warm_block.load_labware("corning_96_wellplate_360ul_flat")
temp_mod.set_temperature(37)
pipette.transfer(50, warm_plate["A1"], reaction_plate.wells())
temp_mod.deactivate()
Cooling After Thermal Processing
temp_mod = protocol.load_module("temperature module gen2", "D3")
cooling_block = temp_mod.load_adapter("opentrons_96_well_aluminum_block")
temp_mod.set_temperature(4)
protocol.move_labware(hot_plate, temp_mod, use_gripper=True)
protocol.delay(minutes=5)
temp_mod.deactivate()
Temperature-Sensitive Enzyme Reaction
temp_mod = protocol.load_module("temperature module gen2", "D1")
rxn_block = temp_mod.load_adapter("opentrons_96_well_aluminum_block")
rxn_plate = rxn_block.load_labware("opentrons_96_wellplate_200ul_pcr_full_skirt")
pipette.transfer(20, dna_samples, rxn_plate.wells()[:8])
pipette.transfer(5, enzyme_mix, rxn_plate.wells()[:8], mix_after=(3, 15))
temp_mod.set_temperature(37)
protocol.delay(hours=2)
temp_mod.set_temperature(65)
protocol.delay(minutes=20)
temp_mod.set_temperature(4)
temp_mod.deactivate()
Maintaining Temperature During Multi-Step Protocol
cold_storage = protocol.load_module("temperature module gen2", "D1")
cold_block = cold_storage.load_adapter("opentrons_96_well_aluminum_block")
sample_plate = cold_block.load_labware("biorad_96_wellplate_200ul_pcr")
cold_storage.set_temperature(4)
protocol.move_labware(sample_plate, "C2", use_gripper=True)
protocol.move_labware(sample_plate, cold_storage, use_gripper=True)
cold_storage.deactivate()
Integration with Other Modules
With Thermocycler
temp_mod = protocol.load_module("temperature module gen2", "D1")
tc_mod = protocol.load_module("thermocyclerModuleV2")
cold_block = temp_mod.load_adapter("opentrons_96_well_aluminum_block")
sample_plate = cold_block.load_labware("opentrons_96_wellplate_200ul_pcr_full_skirt")
temp_mod.set_temperature(4)
tc_mod.open_lid()
protocol.move_labware(sample_plate, tc_mod, use_gripper=True)
tc_mod.close_lid()
tc_mod.open_lid()
protocol.move_labware(sample_plate, temp_mod, use_gripper=True)
temp_mod.deactivate()
With Heater-Shaker
hs_mod = protocol.load_module("heaterShakerModuleV1", "D1")
temp_mod = protocol.load_module("temperature module gen2", "D2")
temp_mod.set_temperature(4)
hs_mod.set_and_wait_for_temperature(65)
hs_mod.close_labware_latch()
hs_mod.set_and_wait_for_shake_speed(1000)
protocol.delay(minutes=10)
hs_mod.deactivate_shaker()
hs_mod.deactivate_heater()
hs_mod.open_labware_latch()
protocol.move_labware(reaction_plate, temp_mod, use_gripper=True)
protocol.delay(minutes=3)
temp_mod.deactivate()
With Magnetic Block
mag_block = protocol.load_module("magneticBlockV1", "D1")
temp_mod = protocol.load_module("temperature module gen2", "D2")
temp_mod.set_temperature(4)
protocol.move_labware(sample_plate, mag_block, use_gripper=True)
protocol.delay(minutes=3)
pipette.transfer(150, sample_plate.wells(), waste.wells())
protocol.move_labware(sample_plate, temp_mod, use_gripper=True)
pipette.transfer(50, cold_buffer, sample_plate.wells())
temp_mod.deactivate()
Best Practices
- Set temperature before loading samples - Allow module to stabilize
- Deactivate at protocol end - Prevent equipment running indefinitely
- Use GEN2 for better performance - Improved cooling and isolation
- Plan for thermal equilibration - Large temperature changes take time
- Monitor ambient temperature - Affects minimum achievable temperature (4°C target requires cool room)
- Use aluminum blocks - Better thermal contact than direct plate placement
- Avoid pipetting during temperature changes - Wait for "holding at target" status
- Consider thermal mass - More liquid = slower temperature equilibration
- Don't rely on auto-deactivation - Module stays on after protocol ends
- Check compatibility - Verify labware fits adapter/block
Common Mistakes
❌ Pipetting during temperature change:
temp_mod.set_temperature(4)
pipette.transfer(...)
✅ Correct:
temp_mod.set_temperature(4)
if temp_mod.status == "holding at target":
pipette.transfer(...)
❌ Not deactivating module:
temp_mod.set_temperature(4)
✅ Correct:
temp_mod.set_temperature(4)
temp_mod.deactivate()
❌ Temperature out of range:
temp_mod.set_temperature(100)
temp_mod.set_temperature(0)
✅ Correct:
temp_mod.set_temperature(95)
temp_mod.set_temperature(4)
❌ Loading labware before temperature stabilizes:
temp_mod.set_temperature(4)
pipette.transfer(100, warm_samples, temp_block.wells())
✅ Correct:
temp_mod.set_temperature(4)
pipette.transfer(100, warm_samples, temp_block.wells())
Troubleshooting
Module not reaching 4°C:
- Check ambient room temperature (module can't cool below ambient by much)
- Ensure adequate airflow around module
- Verify module is on flat, level surface
- Consider using ice packs as supplement for very cold requirements
Module not reaching high temperatures:
- Verify temperature is ≤95°C
- Check module is not in cold environment
- Allow sufficient time for large thermal mass
Temperature not stable:
- Wait for status to show "holding at target"
- Avoid high-airflow environments
- Ensure good thermal contact between labware and block
- Use appropriate adapter for labware type
Slow temperature changes:
- Normal for large temperature differences
- Use smaller labware/tubes for faster equilibration
- Pre-cool/pre-warm module before critical steps
- Consider thermal mass of samples
Module stays on after protocol:
- This is expected behavior
- Manually deactivate via Opentrons App
- Or add
deactivate() to protocol end
Temperature Limits
| Parameter | Minimum | Maximum | Resolution |
|---|
| Block temperature | 4°C | 95°C | 1°C |
| Cooling capacity | ~4°C below ambient | - | - |
| Heating capacity | - | 95°C | - |
Note: Actual minimum temperature depends on ambient conditions. In warm room (>25°C), reaching 4°C may be difficult.
Advanced Techniques
Temperature Gradient Protocol
temp_mod = protocol.load_module("temperature module gen2", "D1")
for temp in [4, 20, 37, 55, 70]:
temp_mod.set_temperature(temp)
protocol.comment(f"Now at {temp}°C")
protocol.delay(minutes=5)
temp_mod.deactivate()
Dual Temperature Setup
cold_mod = protocol.load_module("temperature module gen2", "D1")
warm_mod = protocol.load_module("temperature module gen2", "D2")
cold_mod.set_temperature(4)
warm_mod.set_temperature(37)
pipette.transfer(10, cold_mod.labware["A1"], reaction_plate.wells())
pipette.transfer(50, warm_mod.labware["A1"], reaction_plate.wells())
cold_mod.deactivate()
warm_mod.deactivate()
Temperature Shock Protocol
temp_mod = protocol.load_module("temperature module gen2", "D1")
cell_plate = temp_mod.load_labware("corning_96_wellplate_360ul_flat")
temp_mod.set_temperature(4)
protocol.delay(minutes=20)
temp_mod.set_temperature(42)
protocol.delay(seconds=45)
temp_mod.set_temperature(37)
protocol.delay(minutes=5)
temp_mod.deactivate()
GEN2 vs GEN1
| Feature | GEN1 | GEN2 |
|---|
| Temperature range | 4-95°C | 4-95°C |
| Cooling | Basic | Improved with insulation |
| Thermocycler compatibility | Poor cooling | Good cooling |
| Plate insulation | None | Plastic shroud |
| Block shrouds | No | Yes |
| API | Same | Same |
| Recommended | No | Yes |
Recommendation: Use GEN2 for all new protocols.
API Version Requirements
- Minimum API version: 2.0 (temperature module support)
- Standalone adapters: API 2.15+
- Recommended: 2.19+ for full feature support
Additional Resources
Related Skills
opentrons - Main Opentrons Python API skill
opentrons-heater-shaker - Temperature control with mixing (37-95°C)
opentrons-thermocycler - PCR thermal cycling (4-99°C block)
opentrons-gripper - Automated labware movement (Flex)
opentrons-magnetic-block - Magnetic bead separation