def test_fail_set_temp_deck_temperature(monkeypatch): import types from opentrons.drivers import serial_communication error_msg = 'ERROR: some error here' def _raise_error(self, command, ack, serial_connection, timeout=None): nonlocal error_msg return error_msg serial_communication.write_and_return = types.MethodType( _raise_error, serial_communication) from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False res = temp_deck.set_temperature(-9) assert res == error_msg error_msg = 'Alarm: something alarming happened here' def _raise_error(self, command, ack, serial_connection, timeout=None): nonlocal error_msg return error_msg serial_communication.write_and_return = types.MethodType( _raise_error, serial_communication) res = temp_deck.set_temperature(-9) assert res == error_msg
def test_get_device_info(monkeypatch): import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False command_log = [] model = 'temp-v1' firmware_version = 'edge-1a2b345' serial = 'td20180102A01' def _mock_send_command(self, command, timeout=None, tag=None): nonlocal command_log command_log += [command] return 'model:' + model \ + ' version:' + firmware_version \ + ' serial:' + serial temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) res = temp_deck.get_device_info() assert res == { 'model': model, 'version': firmware_version, 'serial': serial }
def test_fail_get_temp_deck_temperature(): # Get the curent and target temperatures # If no target temp has been previously set, # then the response will set 'T' to 'none' import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False return_string = 'T:none C:90' def _mock_send_command(self, command, timeout=None): return return_string temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) temp_deck.update_temperature() assert temp_deck._temperature == {'current': 90, 'target': None} return_string = 'Tx:none C:1' def _mock_send_command(self, command, timeout=None): return return_string temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) temp_deck.update_temperature() assert temp_deck._temperature == {'current': 90, 'target': None}
def test_get_temp_deck_temperature(): # Get the curent and target temperatures # If no target temp has been previously set, # then the response will set 'T' to 'none' import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False command_log = [] return_string = 'T:none C:90' def _mock_send_command(self, command, timeout=None, tag=None): nonlocal command_log, return_string command_log += [command] return return_string temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) assert temp_deck.temperature == 25 # driver's initialized value assert temp_deck.target is None temp_deck.update_temperature() assert command_log == ['M105'] assert temp_deck.temperature == 90 assert temp_deck.target is None command_log = [] return_string = 'T:99 C:90' temp_deck.update_temperature() assert command_log == ['M105'] assert temp_deck.temperature == 90 assert temp_deck.target == 99
async def test_set_temp_deck_temperature(monkeypatch): # Set target temperature import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False command_log = [] def _mock_send_command(self, command, timeout=None, tag=None): nonlocal command_log command_log += [command] return '' def _mock_update_temp(self): return 'holding at target' temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) temp_deck._update_temp = types.MethodType(_mock_send_command, temp_deck) try: await asyncio.wait_for(temp_deck.set_temperature(99), timeout=0.2) except asyncio.TimeoutError: pass assert command_log[-1] == 'M104 S99.0' try: await asyncio.wait_for(temp_deck.set_temperature(-9), timeout=0.2) except asyncio.TimeoutError: pass assert command_log[-1] == 'M104 S-9.0'
def connect(self): """ Connect to the 'TempDeck' port Planned change- will connect to the correct port in case of multiple TempDecks """ if self._port: self._driver = TempDeckDriver() self._driver.connect(self._port) self._device_info = self._driver.get_device_info() Thread(target=self._poll_temperature).start() else: # Sanity check Should never happen, because connect should never # be called without a port on Module raise MissingDevicePortError( "TempDeck couldnt connect to port {}".format(self._port))
def test_fail_get_temp_deck_temperature(): # Get the curent and target temperatures # If get fails, temp_deck temperature is not updated import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False done = False def _mock_send_command1(self, command, timeout=None, tag=None): nonlocal done done = True return 'T:none C:90' temp_deck._send_command = types.MethodType(_mock_send_command1, temp_deck) temp_deck.update_temperature() time.sleep(0.25) while not done: time.sleep(0.25) assert temp_deck._temperature == {'current': 90, 'target': None} def _mock_send_command2(self, command, timeout=None, tag=None): nonlocal done done = True return 'Tx:none C:1' # Failure premise temp_deck._send_command = types.MethodType(_mock_send_command2, temp_deck) done = False temp_deck.update_temperature() time.sleep(0.25) while not done: time.sleep(0.25) assert temp_deck._temperature == {'current': 90, 'target': None}
def test_set_temp_deck_temperature(monkeypatch): # Set target temperature import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False command_log = [] def _mock_send_command(self, command, timeout=None): nonlocal command_log command_log += [command] return '' temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) temp_deck.set_temperature(99) assert command_log[-1] == 'M104 S99.0' temp_deck.set_temperature(-9) assert command_log[-1] == 'M104 S-9.0'
def connect(self): """ Connect to the 'TempDeck' port Planned change- will connect to the correct port in case of multiple TempDecks """ if self._port: if temp_locks.get(self._port): self._driver = temp_locks[self._port][1] else: self._driver = TempDeckDriver() if not self._driver.is_connected(): self._driver.connect(self._port) self._device_info = self._driver.get_device_info() self._poll_stop_event = Event() Thread(target=self._poll_temperature, daemon=True).start() else: # Sanity check Should never happen, because connect should never # be called without a port on Module raise MissingDevicePortError( "TempDeck couldn't connect to port {}".format(self._port))
def test_dfu_command(monkeypatch): import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False command_log = [] def _mock_send_command(self, command, timeout=None, tag=None): nonlocal command_log command_log += [command] return '' temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) temp_deck.enter_programming_mode() assert command_log == ['dfu']
def test_turn_off_temp_deck(monkeypatch): import types from opentrons.drivers.temp_deck import TempDeck temp_deck = TempDeck() temp_deck.simulating = False command_log = [] def _mock_send_command(self, command, timeout=None, tag=None): nonlocal command_log command_log += [command] return '' temp_deck._send_command = types.MethodType(_mock_send_command, temp_deck) temp_deck.deactivate() assert command_log == ['M18']
class TempDeck(commands.CommandPublisher): """ Under development. API subject to change without a version bump """ def __init__(self, lw=None, port=None, broker=None): super().__init__(broker) self.labware = lw self._port = port self._driver = None self._device_info = None self._poll_stop_event = None @commands.publish.both(command=commands.tempdeck_set_temp) def set_temperature(self, celsius): """ Set temperature in degree Celsius Range: 4 to 95 degree Celsius (QA tested). The internal temp range is -9 to 99 C, which is limited by the 2-digit temperature display. Any input outside of this range will be clipped to the nearest limit """ if self._driver and self._driver.is_connected(): self._driver.legacy_set_temperature(celsius) @commands.publish.both(command=commands.tempdeck_deactivate) def deactivate(self): """ Stop heating/cooling and turn off the fan """ if self._driver and self._driver.is_connected(): self._driver.deactivate() def wait_for_temp(self): """ This method exits only if set temperature has reached.Subject to change """ if self._driver and self._driver.is_connected(): while self.status != 'holding at target': pass @classmethod def name(cls): return 'tempdeck' @classmethod def display_name(cls): return 'Temperature Deck' # TODO: there should be a separate decoupled set of classes that construct # the http api response entity given the model instance. def to_dict(self): return { 'name': self.name(), 'port': self.port, 'serial': self.device_info and self.device_info.get('serial'), 'model': self.device_info and self.device_info.get('model'), 'fwVersion': self.device_info and self.device_info.get('version'), 'displayName': self.display_name(), **self.live_data } @property def live_data(self): return { 'status': self.status, 'data': { 'currentTemp': self.temperature, 'targetTemp': self.target } } @property def port(self): """ Serial Port """ return self._port @property def device_info(self): """ Returns a dict: { 'serial': 'abc123', 'model': '8675309', 'version': '9001' } """ return self._device_info @property def temperature(self): """ Current temperature in degree celsius """ return self._driver.temperature @property def target(self): """ Target temperature in degree celsius. Returns None if no target set """ return self._driver.target @property def status(self): """ Returns a string: 'heating'/'cooling'/'holding at target'/'idle'. NOTE: Depends on _poll_temperature thread to update the temperature to be used to determine the status """ return self._driver and self._driver.status # Internal Methods def _poll_temperature(self): while not self._poll_stop_event.wait(TEMP_POLL_INTERVAL_SECS): self._driver and self._driver.update_temperature() def connect(self): """ Connect to the 'TempDeck' port Planned change- will connect to the correct port in case of multiple TempDecks """ if self._port: if temp_locks.get(self._port): self._driver = temp_locks[self._port][1] else: self._driver = TempDeckDriver() if not self._driver.is_connected(): self._driver.connect(self._port) self._device_info = self._driver.get_device_info() self._poll_stop_event = Event() Thread(target=self._poll_temperature, daemon=True).start() else: # Sanity check Should never happen, because connect should never # be called without a port on Module raise MissingDevicePortError( "TempDeck couldn't connect to port {}".format(self._port)) def disconnect(self): ''' Disconnect from the serial port ''' if self._poll_stop_event: self._poll_stop_event.set() if self._driver: if self.status != 'idle': self.deactivate() self._driver.disconnect(port=self._port)
def temp_deck(): temp_deck = TempDeck() temp_deck.simulating = False temp_deck._lock = Lock() yield temp_deck temp_deck._lock = None
# Variables are case sensitive Plasmid1_wells = [Compcells.cols['B']['2':'11':2] + Compcells.cols['C']['2':'11':2] + Compcells.cols['D']['2':'11':2] # Prevents the use of outside rows and columns, wells to add plasmid 1 to + Compcells.cols['D']['2':'11':2] + Compcells.cols['E']['2':'11':2] + Compcells.cols['F']['2':'11':2]] # Specify the target wells that you want to have bacterial aliquots in # Change Compcells to match whatever the container with the competent cells is called, Line 15 Plasmid2_wells = [] # The letter specifies the column, the numbers specify the range i.e 2 to 11, the third number specifies steps, 2 to 11 in steps of 2 # Additional List can be added, but these list need to be included in the All_wells array All_wells = [Plasmid1_wells, Plasmid2_wells] # Creates an array from the lists of wells. More lists can be declared and added to this array # By adding in another variable to this section a second list for cells requiring a different plasmid can be used # A third variable would be needed to house both lists and could be used to iterate through the loops with each smaller list being for each plasmid, biglist = [list1,list2], biglist[0] #All_Wells = Randomizer(All_wells) # Randomizes the wells, delete the hashtag to allow this randomizer to run. Imported from OT2_Functions ######################################################################################### ######################################################################################### tempdeck = TempDeck() # Saves the temperature deck into a variable, temperature = {"temp1": 4, "temp2": 42, "temp3": 37} # Saves the temperatures for the protocol into a dictionary. Dictionaries have keys and values # The value can be called by the key i.e temperature["temp1"] = 4 if not robot.is_simulating(): # If the robot is inactive and the temperature deck isn't processing a command tempdeck.connect('/dev/ttyACM0') # Connects to and begins cooling the temperature deck tempdeck.set_temperature(temperature["temp1"]) # Initialization temperature for cooling tempdeck.wait_for_temp() # Pauses the protocol until the temperature deck reaches the set temperature target = All_wells # Adds the array of wells into a variable for easier readability during manipulation SOB_wells = [well.top(1) for well in target] # well.top moves the pipette to the top of the well, the number specifies the distance in mm robot.pause() # Opentron command that pauses whatever the robot is doing. The user can remove and centrifuge at this point, if the need is there. resumed via the OT app # The code below handles distributing plasmid DNA for i in range(NumberofPlasmids): # Transfers plasmid DNA into competent cell aliquots. The variable NumberofPlasmids controls how many times the loop is carried out, once for each plasmid P10.distribute( # Presumes same plasmid for all cells, adds all doses to the pipette, wells specified later in the block
'F10' ] Buffers_positions = Buffers.wells( 'A1', length=25 ) # Specify the buffer positions, change length=25 to whatever the number # of buffers you have, eg if 15 buffers length=15 ######################################################################################### ######################################################################################### # BELOW IS CODE FOR THE PROTOCOL # IF WORKING WITH E. COLI, BELOW IS A OPTIMAL PROTOCOL THAT ONLY REQUIRES 1 WASH STEP # IF INVESTINGATING DIFFERENT INCUBATION TIMES, ALTER P300 DELAYS # IF WANTING TO CHANGE TEMPDECK ON CONSTANTLY, REMOVE ALL tempdeck.disengage() AND PLACE BEFORE # FINAL ROBOT COMMENT tempdeck = TempDeck() # Connects the Tempdeck module to OT-2 if not robot.is_simulating(): # Cannot use while simulating, tempdeck.connect('/dev/ttyACM0') tempdeck.set_temperature( target_temperature) # Sets the temperature to whats specified above target1 = Compcells1(Even_wells) # Where your cells are going robot.home() # turbulent airflow within the OT-2 robot.pause() robot.comment( "Make sure that centrifuge has been chilled down to 4*C and all buffers are on ice." ) robot.comment( "All plates should be chilled at the beginning and culture should be incubated on ice for 15 minutes before start."
'E9', 'F2', 'F4', 'F6', 'F8', 'F10' ] Buffers_positions = Buffers.wells('A1', length=25) target_temperature = 4 # Specified temperatures for cold incubated, target_temperature1 = 4 # heat shock and recovery incubation target_temperature2 = 42 target_temperature3 = 37 # first position in reagent_pos list tempdeck = TempDeck() # Connects the Tempdeck module to OT-2 ######################################################################################### ######################################################################################### robot.home() #No.1 for counter, reagent in enumerate(reagents1, 0): # These objects are temporary and will only exist within this loop source = reagent_pos1[ counter] # Counter is use to index an independent list (e.g. reagent_pos) P10list = [source] # This is then added to both list P300list = [source] P300.pick_up_tip( ) # Picks up pipette tip for both P10 and P300 to allow to alternate P10.pick_up_tip()