Skip to content

Commit

Permalink
refactor(api): clean up TC context naming and behavior (#4003)
Browse files Browse the repository at this point in the history
As a final pass before beta testing, this incorporates standardized behavior into the TC context,
and alters naming in the interest of clarity and developer experience. The major behavior changes can be summed up as making all long running temperature setting methods blocking by default. Added functionality down the road will reopen context affordances to allow for performing other tasks during ramp up or ramp down of a given peltier.

Closes #3981
  • Loading branch information
b-cooper authored Sep 6, 2019
1 parent 6d42fc3 commit 6c60457
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 139 deletions.
77 changes: 50 additions & 27 deletions api/src/opentrons/commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,33 +371,48 @@ def tempdeck_deactivate():


def thermocycler_open():
text = "Opening thermocycler lid"
text = "Opening Thermocycler lid"
return make_command(
name=command_types.THERMOCYCLER_OPEN,
payload={'text': text}
)


def thermocycler_set_temp(temperature, hold_time):
text = "Setting thermocycler temperature to {temperature} °C ".format(
temperature=temperature)
if hold_time is not None:
text += " with a hold time of {} seconds".format(hold_time)
return make_command(
name=command_types.THERMOCYCLER_SET_TEMP,
def thermocycler_set_block_temp(temperature,
hold_time_seconds,
hold_time_minutes):
text = f'Setting Thermocycler well block temperature to {temperature} °C '
total_seconds = None
# TODO: BC 2019-09-05 this time resolving logic is partially duplicated
# in the thermocycler api class definition, with this command logger
# implementation, there isn't a great way to avoid this, but it should
# be consolidated as soon as an alternative to the publisher is settled on.
if hold_time_seconds or hold_time_minutes:
given_seconds = hold_time_seconds or 0
given_minutes = hold_time_minutes or 0
total_seconds = given_seconds + (given_minutes * 60)

clean_seconds = total_seconds % 60
clean_minutes = (total_seconds - clean_seconds) / 60
text += f'with a hold time of '
if clean_minutes > 0:
text += f'{clean_minutes} minutes and '
text += f'{clean_seconds} seconds'
return make_command(
name=command_types.THERMOCYCLER_SET_BLOCK_TEMP,
payload={
'temperature': temperature,
'hold_time': hold_time,
'hold_time': total_seconds,
'text': text
}
)


def thermocycler_cycle_temperatures(steps, repetitions):
def thermocycler_execute_profile(steps, repetitions):
text = f'Thermocycler starting {repetitions} repetitions' \
' of cycle composed of the following steps: {steps}'
return make_command(
name=command_types.THERMOCYCLER_CYCLE_TEMPS,
name=command_types.THERMOCYCLER_EXECUTE_PROFILE,
payload={
'text': text,
'steps': steps
Expand All @@ -414,49 +429,57 @@ def thermocycler_wait_for_hold():


def thermocycler_wait_for_temp():
text = "Waiting for thermocycler to reach target"
text = "Waiting for Thermocycler to reach target"
return make_command(
name=command_types.THERMOCYCLER_WAIT_FOR_TEMP,
payload={'text': text}
)


def thermocycler_heat_lid():
text = "Heating thermocycler lid"
def thermocycler_set_lid_temperature(temperature):
text = f'Setting Thermocycler lid temperature to {temperature} °C '
return make_command(
name=command_types.THERMOCYCLER_HEAT_LID,
name=command_types.THERMOCYCLER_SET_LID_TEMP,
payload={'text': text}
)


def thermocycler_stop_lid_heating():
text = "Deactivating lid heating"
def thermocycler_deactivate_lid():
text = "Deactivating Thermocycler lid heating"
return make_command(
name=command_types.THERMOCYCLER_STOP_LID_HEATING,
name=command_types.THERMOCYCLER_DEACTIVATE_LID,
payload={'text': text}
)


def thermocycler_wait_for_lid_temp():
text = "Waiting for lid to reach target temperature"
def thermocycler_deactivate_block():
text = "Deactivating Thermocycler well block heating"
return make_command(
name=command_types.THERMOCYCLER_WAIT_FOR_LID_TEMP,
name=command_types.THERMOCYCLER_DEACTIVATE_BLOCK,
payload={'text': text}
)


def thermocycler_close():
text = "Closing thermocycler lid"
def thermocycler_deactivate():
text = "Deactivating Thermocycler"
return make_command(
name=command_types.THERMOCYCLER_CLOSE,
name=command_types.THERMOCYCLER_DEACTIVATE,
payload={'text': text}
)


def thermocycler_deactivate():
text = "Deactivating thermocycler"
def thermocycler_wait_for_lid_temp():
text = "Waiting for Thermocycler lid to reach target temperature"
return make_command(
name=command_types.THERMOCYCLER_DEACTIVATE,
name=command_types.THERMOCYCLER_WAIT_FOR_LID_TEMP,
payload={'text': text}
)


def thermocycler_close():
text = "Closing Thermocycler lid"
return make_command(
name=command_types.THERMOCYCLER_CLOSE,
payload={'text': text}
)

Expand Down
14 changes: 9 additions & 5 deletions api/src/opentrons/commands/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ def makeRobotCommandName(name):

THERMOCYCLER_OPEN = makeRobotCommandName('THERMOCYCLER_OPEN')
THERMOCYCLER_CLOSE = makeRobotCommandName('THERMOCYCLER_CLOSE')
THERMOCYCLER_SET_TEMP = makeRobotCommandName('THERMOCYCLER_SET_TEMP')
THERMOCYCLER_CYCLE_TEMPS = makeRobotCommandName('THERMOCYCLER_CYCLE_TEMPS')
THERMOCYCLER_SET_BLOCK_TEMP = makeRobotCommandName(
'THERMOCYCLER_SET_BLOCK_TEMP')
THERMOCYCLER_EXECUTE_PROFILE = makeRobotCommandName(
'THERMOCYCLER_EXECUTE_PROFILE')
THERMOCYCLER_DEACTIVATE = makeRobotCommandName('THERMOCYCLER_DEACTIVATE')
THERMOCYCLER_WAIT_FOR_HOLD = makeRobotCommandName('THERMOCYCLER_WAIT_FOR_HOLD')
THERMOCYCLER_WAIT_FOR_TEMP = makeRobotCommandName('THERMOCYCLER_WAIT_FOR_TEMP')
THERMOCYCLER_WAIT_FOR_LID_TEMP = makeRobotCommandName(
'THERMOCYCLER_WAIT_FOR_LID_TEMP')
THERMOCYCLER_HEAT_LID = makeRobotCommandName('THERMOCYCLER_HEAT_LID')
THERMOCYCLER_STOP_LID_HEATING = makeRobotCommandName(
'THERMOCYCLER_STOP_LID_HEATING')
THERMOCYCLER_SET_LID_TEMP = makeRobotCommandName('THERMOCYCLER_SET_LID_TEMP')
THERMOCYCLER_DEACTIVATE_LID = makeRobotCommandName(
'THERMOCYCLER_DEACTIVATE_LID')
THERMOCYCLER_DEACTIVATE_BLOCK = makeRobotCommandName(
'THERMOCYCLER_DEACTIVATE_BLOCK')
2 changes: 1 addition & 1 deletion api/src/opentrons/drivers/thermocycler/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ async def set_temperature(self,
if retries > TEMP_UPDATE_RETRIES:
break

async def set_lid_temperature(self, temp: Optional[float]) -> None:
async def set_lid_temperature(self, temp: float) -> None:
if temp is None:
self._lid_target = LID_TARGET_DEFAULT
else:
Expand Down
17 changes: 15 additions & 2 deletions api/src/opentrons/hardware_control/modules/thermocycler.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,19 @@ async def close(self) -> str:
return await self._driver.close()

async def set_temperature(self, temperature,
hold_time=None, ramp_rate=None):
hold_time_seconds: float = None,
hold_time_minutes: float = None,
ramp_rate=None):
seconds = hold_time_seconds if hold_time_seconds is not None else 0
minutes = hold_time_minutes if hold_time_minutes is not None else 0
total_seconds = seconds + (minutes * 60)
hold_time = total_seconds if total_seconds > 0 else 0
await self._driver.set_temperature(
temp=temperature, hold_time=hold_time, ramp_rate=ramp_rate)
if hold_time:
await self.wait_for_hold()
else:
await self.wait_for_temp()

async def _execute_cycles(self,
steps: List[types.ThermocyclerStep],
Expand All @@ -224,9 +232,10 @@ async def cycle_temperatures(self,
self._current_cycle_task = cycle_task
await cycle_task

async def set_lid_temperature(self, temp: Optional[float]):
async def set_lid_temperature(self, temp: float):
""" Set the lid temperature in deg Celsius """
await self._driver.set_lid_temperature(temp=temp)
await self.wait_for_lid_temp()

async def stop_lid_heating(self):
return await self._driver.stop_lid_heating()
Expand Down Expand Up @@ -268,6 +277,10 @@ def lid_temp(self):
def lid_status(self):
return self._driver.lid_status

@property
def lid_temp_status(self):
return self._driver.lid_temp_status

@property
def ramp_rate(self):
return self._driver.ramp_rate
Expand Down
Loading

0 comments on commit 6c60457

Please sign in to comment.