示例#1
0
async def save_z(data) -> CommandResult:
    """
    Save the current Z height value for the calibration data

    :param data: unused
    """
    if not session_wrapper.session:
        raise NoSessionInProgress()

    if not session_wrapper.session.tip_length:
        message = "Tip length must be set before calibrating"
        status = False
    else:
        session_wrapper.session.z_value = position(
            session_wrapper.session.current_mount,
            session_wrapper.session.adapter,
            session_wrapper.session.cp)[-1]

        session_wrapper.session.current_transform[2][3] =\
            session_wrapper.session.z_value

        session_wrapper.session.adapter.update_config(
            gantry_calibration=list(
                list(i) for i in session_wrapper.session.current_transform
            )
        )

        message = "Saved z: {}".format(session_wrapper.session.z_value)
        status = True

    return CommandResult(success=status, message=message)
示例#2
0
async def save_xy(data) -> CommandResult:
    """
    Save the current XY values for the calibration data

    :param data: a dict with schema:
    {
      'point': a string ID ['1', '2', or '3'] of the calibration point to save
    }
    """
    if not session_wrapper.session:
        raise NoSessionInProgress()

    valid_points = list(session_wrapper.session.points.keys())
    point = data.get('point')
    if point not in valid_points:
        message = 'point must be one of {}'.format(valid_points)
        status = False
    elif not session_wrapper.session.current_mount:
        message = "Mount must be set before calibrating"
        status = False
    else:
        x, y, _ = position(
            session_wrapper.session.current_mount,
            session_wrapper.session.adapter,
            session_wrapper.session.cp)

        session_wrapper.session.points[point] = (x, y)
        message = "Saved point {} value: {}".format(
            point, session_wrapper.session.points[point])
        status = True

    return CommandResult(success=status, message=message)
示例#3
0
async def save_xy(data):
    """
    Save the current XY values 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 xy'
      'point': a string ID ['1', '2', or '3'] of the calibration point to save
    }
    """
    valid_points = list(session_wrapper.session.points.keys())
    point = data.get('point')
    if point not in valid_points:
        message = 'point must be one of {}'.format(valid_points)
        status = 400
    elif not session_wrapper.session.current_mount:
        message = "Mount must be set before calibrating"
        status = 400
    else:
        if not feature_flags.use_protocol_api_v2():
            mount = 'Z' if session_wrapper.session.current_mount == 'left'\
                else 'A'
            x, y, _ = position(mount, session_wrapper.session.adapter)
            if session_wrapper.session.pipettes[
                    session_wrapper.session.current_mount].channels != 1:
                # See note in `move`
                y = y - pipette_config.Y_OFFSET_MULTI
            if session_wrapper.session.current_mount == 'left':
                dx, dy, _ = session_wrapper.session.adapter.config.mount_offset
                x = x + dx
                y = y + dy
        else:
            x, y, _ = position(
                session_wrapper.session.current_mount,
                session_wrapper.session.adapter,
                session_wrapper.session.cp)

        session_wrapper.session.points[point] = (x, y)
        message = "Saved point {} value: {}".format(
            point, session_wrapper.session.points[point])
        status = 200
    return web.json_response({'message': message}, status=status)
示例#4
0
async def save_xy(data) -> CommandResult:
    """
    Save the current XY values for the calibration data

    :param data: a dict with schema:
    {
      'point': a string ID ['1', '2', or '3'] of the calibration point to save
    }
    """
    if not session_wrapper.session:
        raise NoSessionInProgress()

    valid_points = list(session_wrapper.session.points.keys())
    point = data.get('point')
    if point not in valid_points:
        message = 'point must be one of {}'.format(valid_points)
        status = False
    elif not session_wrapper.session.current_mount:
        message = "Mount must be set before calibrating"
        status = False
    else:
        if not feature_flags.use_protocol_api_v2():
            mount = 'Z' if session_wrapper.session.current_mount == 'left'\
                else 'A'
            x, y, _ = position(mount, session_wrapper.session.adapter)
            if session_wrapper.session.pipettes[
                    session_wrapper.session.current_mount].channels != 1:
                # See note in `move`
                y = y - pipette_config.Y_OFFSET_MULTI
            if session_wrapper.session.current_mount == 'left':
                dx, dy, _ = session_wrapper.session.adapter.config.mount_offset
                x = x + dx
                y = y + dy
        else:
            x, y, _ = position(session_wrapper.session.current_mount,
                               session_wrapper.session.adapter,
                               session_wrapper.session.cp)

        session_wrapper.session.points[point] = (x, y)
        message = "Saved point {} value: {}".format(
            point, session_wrapper.session.points[point])
        status = True

    return CommandResult(success=status, message=message)
示例#5
0
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_wrapper.session.tip_length:
        message = "Tip length must be set before calibrating"
        status = 400
    else:
        if not feature_flags.use_protocol_api_v2():
            mount = 'Z' if session_wrapper.session.current_mount == 'left' \
                else 'A'
            actual_z = position(
                mount, session_wrapper.session.adapter)[-1]
            length_offset = pipette_config.load(
                session_wrapper.session.current_model,
                session_wrapper.session.pipette_id).model_offset[-1]
            session_wrapper.session.z_value =\
                actual_z - session_wrapper.session.tip_length + length_offset
        else:
            session_wrapper.session.z_value = position(
                session_wrapper.session.current_mount,
                session_wrapper.session.adapter,
                session_wrapper.session.cp)[-1]

        session_wrapper.session.current_transform[2][3] =\
            session_wrapper.session.z_value

        session_wrapper.session.adapter.update_config(
            gantry_calibration=list(
                list(i) for i in session_wrapper.session.current_transform
            )
        )

        message = "Saved z: {}".format(session_wrapper.session.z_value)
        status = 200
    return web.json_response({'message': message}, status=status)
示例#6
0
async def test_set_and_jog_integration(
        async_client, async_server, monkeypatch):
    """
    Test that the jog function works.
    Note that in order for the jog function to work, the following must
    be done:
    1. Create a session manager

    Then jog requests will work as expected.
    """
    test_model = 'p300_multi_v1'
    hardware = async_server['com.opentrons.hardware']
    # Why does this need to be awaited for a synch adapter
    await hardware.cache_instruments(
        {types.Mount.LEFT: None, types.Mount.RIGHT: test_model})

    dummy_token = 'Test Token'

    def uuid_mock():
        return dummy_token

    monkeypatch.setattr(endpoints, '_get_uuid', uuid_mock)

    token_res = await async_client.post('/calibration/deck/start')
    assert token_res.status == 201, token_res
    token_text = await token_res.json()
    token = token_text['token']

    axis = 'z'
    direction = 1
    step = 3
    # left pipette z carriage motor is smoothie axis "Z", right is "A"
    sess = dc.endpoints.session
    sess.adapter.home()
    prior_x, prior_y, prior_z = dc.position(
        sess.current_mount, sess.adapter, sess.cp)

    resp = await async_client.post(
        '/calibration/deck',
        json={
            'token': token,
            'command': 'jog',
            'axis': axis,
            'direction': direction,
            'step': step
        })

    body = await resp.json()
    msg = body.get('message')

    assert '{}'.format((prior_x, prior_y, prior_z + step)) in msg
示例#7
0
async def save_z(data) -> CommandResult:
    """
    Save the current Z height value for the calibration data

    :param data: unused
    """
    if not session_wrapper.session:
        raise NoSessionInProgress()

    if not session_wrapper.session.tip_length:
        message = "Tip length must be set before calibrating"
        status = False
    else:
        if not feature_flags.use_protocol_api_v2():
            mount = 'Z' if session_wrapper.session.current_mount == 'left' \
                else 'A'
            actual_z = position(mount, session_wrapper.session.adapter)[-1]
            length_offset = pipette_config.load(
                session_wrapper.session.current_model,
                session_wrapper.session.pipette_id).model_offset[-1]
            session_wrapper.session.z_value =\
                actual_z - session_wrapper.session.tip_length + length_offset
        else:
            session_wrapper.session.z_value = position(
                session_wrapper.session.current_mount,
                session_wrapper.session.adapter,
                session_wrapper.session.cp)[-1]

        session_wrapper.session.current_transform[2][3] =\
            session_wrapper.session.z_value

        session_wrapper.session.adapter.update_config(gantry_calibration=list(
            list(i) for i in session_wrapper.session.current_transform))

        message = "Saved z: {}".format(session_wrapper.session.z_value)
        status = True

    return CommandResult(success=status, message=message)
示例#8
0
async def test_set_and_jog_integration(async_client, monkeypatch):
    """
    Test that the jog function works.
    Note that in order for the jog function to work, the following must
    be done:
    1. Create a session manager

    Then jog requests will work as expected.
    """
    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()
    dummy_token = 'Test Token'

    def uuid_mock():
        return dummy_token

    monkeypatch.setattr(endpoints, '_get_uuid', uuid_mock)

    token_res = await async_client.post('/calibration/deck/start')
    token_text = await token_res.json()
    token = token_text['token']

    axis = 'z'
    direction = 1
    step = 3
    # left pipette z carriage motor is smoothie axis "Z", right is "A"
    sess = dc.endpoints.session
    smoothie_axis = 'Z' if sess.current_mount == 'left' else 'A'

    robot.reset()
    prior_x, prior_y, prior_z = dc.position(smoothie_axis)
    resp = await async_client.post('/calibration/deck',
                                   json={
                                       'token': token,
                                       'command': 'jog',
                                       'axis': axis,
                                       'direction': direction,
                                       'step': step
                                   })

    body = await resp.json()
    msg = body.get('message')

    assert '{}'.format((prior_x, prior_y, prior_z + step)) in msg
示例#9
0
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)
示例#10
0
async def move(data) -> CommandResult:
    """
    Allow the user to move the selected pipette to a specific point

    :param data: a dict with schema:
    {
      'point': The name of the point to move to. Must be one of
               ["1", "2", "3", "safeZ", "attachTip"]
    }
    :return: The position you are moving to
    """
    if not session_wrapper.session:
        raise NoSessionInProgress()

    point_name = data.get('point')
    point = safe_points().get(str(point_name))
    if point and len(point) == 3:
        if not feature_flags.use_protocol_api_v2():
            pipette = session_wrapper.session.pipettes[
                session_wrapper.session.current_mount]
            channels = pipette.channels
            # For multichannel pipettes in the V1 session, we use the tip closest
            # to the front of the robot rather than the back (this is the tip that
            # would go into well H1 of a plate when pipetting from the first row of
            # a 96 well plate, for instance). Since moves are issued for the A1 tip
            # we have to adjust the target point by 2 * Y_OFFSET_MULTI (where the
            # offset value is the distance from the axial center of the pipette to
            # the A1 tip). By sending the A1 tip to to the adjusted target, the H1
            # tip should go to the desired point. Y_OFFSET_MULT must then be backed
            # out of xy positions saved in the `save_xy` handler
            # (not 2 * Y_OFFSET_MULTI, because the axial center of the pipette
            # will only be off by 1* Y_OFFSET_MULTI).
            if not channels == 1:
                x = point[0]
                y = point[1] + pipette_config.Y_OFFSET_MULTI * 2
                z = point[2]
                point = (x, y, z)
            # hack: z=150mm is not a safe point for a gen2 pipette with a tip
            # attached, since their home location is z=+172mm and both 300ul
            # and 1000ul tips are more than 22mm long. This isn't an issue for
            # apiv2 because it can select the NOZZLE critical point.
            if pipette.tip_attached and point_name == 'attachTip':
                point = (point[0], point[1], point[2] - pipette._tip_length)

            pipette.move_to((session_wrapper.session.adapter.deck, point),
                            strategy='arc')
        else:
            if not point_name == 'attachTip':
                intermediate_pos = position(
                    session_wrapper.session.current_mount,
                    session_wrapper.session.adapter,
                    session_wrapper.session.cp)
                session_wrapper.session.adapter.move_to(
                    session_wrapper.session.current_mount,
                    Point(x=intermediate_pos[0],
                          y=intermediate_pos[1],
                          z=session_wrapper.session.tip_length),
                    critical_point=session_wrapper.session.cp)
                session_wrapper.session.adapter.move_to(
                    session_wrapper.session.current_mount,
                    Point(x=point[0],
                          y=point[1],
                          z=session_wrapper.session.tip_length),
                    critical_point=session_wrapper.session.cp)
                session_wrapper.session.adapter.move_to(
                    session_wrapper.session.current_mount,
                    Point(x=point[0], y=point[1], z=point[2]),
                    critical_point=session_wrapper.session.cp)
            else:
                if session_wrapper.session.cp == CriticalPoint.TIP:
                    session_wrapper.session.cp = CriticalPoint.NOZZLE
                session_wrapper.session.adapter.move_to(
                    session_wrapper.session.current_mount,
                    Point(x=point[0], y=point[1], z=point[2]),
                    critical_point=session_wrapper.session.cp)
        message = 'Moved to {}'.format(point)
        status = True
    else:
        message = '"point" must be one of "1", "2", "3", "safeZ", "attachTip"'
        status = False

    return CommandResult(success=status, message=message)