|
| 1 | +"""Heat up and wait for a 96ch to reach the desired temperature.""" |
| 2 | + |
| 3 | +from opentrons.protocol_api import ProtocolContext, ParameterContext |
| 4 | +from opentrons.hardware_control.adapters import SynchronousAdapter |
| 5 | +from opentrons.hardware_control.ot3api import OT3API |
| 6 | +from opentrons.hardware_control.types import Axis |
| 7 | +from opentrons_hardware.sensors.sensor_driver import SensorDriver |
| 8 | +from opentrons_hardware.sensors.sensor_types import EnvironmentSensor |
| 9 | +from opentrons_hardware.firmware_bindings.constants import NodeId, SensorId |
| 10 | + |
| 11 | + |
| 12 | +def add_parameters(parameters: ParameterContext) -> None: |
| 13 | + """Build the runtime parameters.""" |
| 14 | + parameters.add_int( |
| 15 | + display_name="model type", |
| 16 | + variable_name="model_type", |
| 17 | + default=50, |
| 18 | + choices=[ |
| 19 | + {"display_name": "50", "value": 50}, |
| 20 | + {"display_name": "1000", "value": 1000}, |
| 21 | + ], |
| 22 | + description="Select model type.", |
| 23 | + ) |
| 24 | + |
| 25 | + parameters.add_int( |
| 26 | + display_name="Target Temperature", |
| 27 | + variable_name="temp", |
| 28 | + default=25.5, |
| 29 | + minimum=20, |
| 30 | + maximum=35, |
| 31 | + description="Set the target temperature for the pre-heat", |
| 32 | + ) |
| 33 | + |
| 34 | + |
| 35 | +metadata = {"protocolName": "8ch Pre-heating protocol"} |
| 36 | + |
| 37 | +requirements = {"robotType": "Flex", "apiLevel": "2.21"} |
| 38 | + |
| 39 | + |
| 40 | +async def read_sensor(self, sensor: EnvironmentSensor) -> float: # noqa: ANN001 |
| 41 | + """Read and return the current sensor information.""" |
| 42 | + s_driver = SensorDriver() |
| 43 | + sensor_data = await s_driver.read( |
| 44 | + can_messenger=self._backend._messenger, |
| 45 | + sensor=sensor, |
| 46 | + offset=False, |
| 47 | + ) |
| 48 | + assert sensor_data.temperature is not None # type: ignore [union-attr] |
| 49 | + return sensor_data.temperature.to_float() # type: ignore [union-attr] |
| 50 | + |
| 51 | + |
| 52 | +def get_motors_hot(ot3api: SynchronousAdapter) -> None: |
| 53 | + """Adjust the motor hold currents to heat quicker.""" |
| 54 | + axis_settings = [Axis.P_L, Axis.Q] |
| 55 | + ot3api.engage_axes(axis_settings) |
| 56 | + |
| 57 | + |
| 58 | +def run(ctx: ProtocolContext) -> None: |
| 59 | + """Run.""" |
| 60 | + ot3api = ctx._core.get_hardware() |
| 61 | + if not ctx.is_simulating(): |
| 62 | + OT3API.read_sensor = read_sensor # type: ignore [attr-defined] |
| 63 | + primary = EnvironmentSensor.build( |
| 64 | + sensor_id=SensorId.S0, |
| 65 | + node_id=NodeId.pipette_left, |
| 66 | + ) |
| 67 | + secondary = EnvironmentSensor.build( |
| 68 | + sensor_id=SensorId.S1, |
| 69 | + node_id=NodeId.pipette_left, |
| 70 | + ) |
| 71 | + _ = ctx.load_instrument( |
| 72 | + f"flex_8channel_{ctx.params.model_type}", "left" # type: ignore [attr-defined] |
| 73 | + ) |
| 74 | + if not ctx.is_simulating(): |
| 75 | + current_temp_1 = ot3api.read_sensor(primary) |
| 76 | + current_temp_2 = ot3api.read_sensor(secondary) |
| 77 | + get_motors_hot(ot3api) # type: ignore [arg-type] |
| 78 | + avg_temp = (current_temp_1 + current_temp_2) / 2 |
| 79 | + target = ctx.params.temp # type: ignore [attr-defined] |
| 80 | + while avg_temp < target: |
| 81 | + current_temp_1 = ot3api.read_sensor(primary) |
| 82 | + current_temp_2 = ot3api.read_sensor(secondary) |
| 83 | + avg_temp = (current_temp_1 + current_temp_2) / 2 |
| 84 | + ctx.delay(seconds=15, msg=f"Current temperature {avg_temp} target={target}") |
0 commit comments