def get_attached_pipettes(self): """ Gets model names of attached pipettes :return: :dict with keys 'left' and 'right' and a model string for each mount, or 'uncommissioned' if no model string available """ left_data = { 'mount_axis': 'z', 'plunger_axis': 'b', 'model': self.model_by_mount['left'], } left_model = left_data.get('model') if left_model: tip_length = pipette_config.load(left_model).tip_length left_data.update({'tip_length': tip_length}) right_data = { 'mount_axis': 'a', 'plunger_axis': 'c', 'model': self.model_by_mount['right'] } right_model = right_data.get('model') if right_model: tip_length = pipette_config.load(right_model).tip_length right_data.update({'tip_length': tip_length}) return {'left': left_data, 'right': right_data}
def set_current_mount(attached_pipettes): """ Choose the pipette in which to execute commands. If there is no pipette, or it is uncommissioned, the pipette is not mounted. :attached_pipettes attached_pipettes: Information obtained from the current pipettes attached to the robot. This looks like the following: :dict with keys 'left' and 'right' and a model string for each mount, or 'uncommissioned' if no model string available :return: The selected pipette """ global session left = attached_pipettes.get('left') right = attached_pipettes.get('right') left_pipette = None right_pipette = None pipette = None model = None if left['model'] in pipette_config.configs: pip_config = pipette_config.load(left['model']) left_pipette = instruments._create_pipette_from_config( mount='left', config=pip_config) if right['model'] in pipette_config.configs: pip_config = pipette_config.load(right['model']) right_pipette = instruments._create_pipette_from_config( mount='right', config=pip_config) if right_pipette and right_pipette.channels == 1: session.current_mount = 'A' pipette = right_pipette model = right['model'] elif left_pipette and left_pipette.channels == 1: session.current_mount = 'Z' pipette = left_pipette model = left['model'] else: if right_pipette: session.current_mount = 'A' pipette = right_pipette model = right['model'] elif left_pipette: session.current_mount = 'Z' pipette = left_pipette model = left['model'] return {'pipette': pipette, 'model': model}
async def test_get_pipettes(virtual_smoothie_env, loop, test_client, monkeypatch): test_model = 'p300_multi_v1' def dummy_read_model(mount): return test_model monkeypatch.setattr(robot._driver, 'read_pipette_model', dummy_read_model) robot.reset() app = init(loop) cli = await loop.create_task(test_client(app)) model = pipette_config.load(test_model) expected = { 'left': { 'model': model.name, 'tip_length': model.tip_length, 'mount_axis': 'z', 'plunger_axis': 'b' }, 'right': { 'model': model.name, 'tip_length': model.tip_length, 'mount_axis': 'a', 'plunger_axis': 'c' } } resp = await cli.get('/pipettes?refresh=true') text = await resp.text() assert resp.status == 200 assert json.loads(text) == expected
def test_all_pipette_models_can_transfer(): from opentrons.instruments import pipette_config models = [ 'p10_single', 'p10_multi', 'p50_single', 'p50_multi', 'p300_single', 'p300_multi', 'p1000_single' ] for m in models: robot.reset() left = instruments._create_pipette_from_config( config=pipette_config.load(m + '_v1'), mount='left') right = instruments._create_pipette_from_config( config=pipette_config.load(m + '_v1.3'), mount='right') left.tip_attached = True right.tip_attached = True left.aspirate().dispense() right.aspirate().dispense()
def load_pipettes(protocol_data): pipettes = protocol_data.get('pipettes', {}) pipettes_by_id = {} for pipette_id, props in pipettes.items(): model = props.get('model') mount = props.get('mount') config = pipette_config.load(model) pipettes_by_id[pipette_id] = instruments._create_pipette_from_config( config=config, mount=mount) return pipettes_by_id
def test_pipette_models_reach_max_volume(): from opentrons.instruments import pipette_config for model in pipette_config.configs: config = pipette_config.load(model) robot.reset() pipette = instruments._create_pipette_from_config(config=config, mount='right') pipette.tip_attached = True pipette.aspirate(pipette.max_volume) pos = pose_tracker.absolute(robot.poses, pipette.instrument_actuator) assert pos[0] < pipette.plunger_positions['top']
def _fetch_or_create_pipette(mount, model=None): existing_pipettes = robot.get_instruments() pipette = None for existing_mount, existing_pipette in existing_pipettes: if existing_mount == mount: pipette = existing_pipette if pipette is None: if model is None: pipette = instruments.Pipette(mount=mount) else: config = pipette_config.load(model) pipette = instruments._create_pipette_from_config(config=config, mount=mount) return pipette
def test_pipette_version_1_0_and_1_3_extended_travel(): from opentrons.instruments import pipette_config models = [ 'p10_single', 'p10_multi', 'p50_single', 'p50_multi', 'p300_single', 'p300_multi', 'p1000_single' ] for m in models: robot.reset() left = instruments._create_pipette_from_config( config=pipette_config.load(m + '_v1'), mount='left') right = instruments._create_pipette_from_config( config=pipette_config.load(m + '_v1.3'), mount='right') # the difference between v1 and v1.3 is that the plunger's travel # distance extended, allowing greater ranges for aspirate/dispense # and blow-out. Test that all v1.3 pipette have larger travel thant v1 left_poses = left.plunger_positions left_diff = left_poses['top'] - left_poses['blow_out'] right_poses = right.plunger_positions right_diff = right_poses['top'] - right_poses['blow_out'] assert right_diff > left_diff
def P50_Single(self, mount, trash_container='', tip_racks=[], aspirate_flow_rate=None, dispense_flow_rate=None): pipette_model_version = self._retrieve_version_number( mount, 'p50_single') config = pipette_config.load(pipette_model_version) return self._create_pipette_from_config( config=config, mount=mount, trash_container=trash_container, tip_racks=tip_racks, aspirate_flow_rate=aspirate_flow_rate, dispense_flow_rate=dispense_flow_rate)
async def save_z(data): """ Save the current Z height value for the calibration data :param data: Information obtained from a POST request. The content type is application/json. The correct packet form should be as follows: { 'token': UUID token from current session start 'command': 'save z' } """ if not session.tip_length: message = "Tip length must be set before calibrating" status = 400 else: actual_z = position(session.current_mount)[-1] length_offset = pipette_config.load( session.current_model).model_offset[-1] session.z_value = actual_z - session.tip_length + length_offset message = "Saved z: {}".format(session.z_value) status = 200 return web.json_response({'message': message}, status=status)