def test_synch_adapter(loop): api = API.build_hardware_simulator(loop=loop) synch = adapters.SynchronousAdapter(api) synch.cache_instruments({Mount.LEFT: 'p10_single'}) assert synch.attached_instruments[Mount.LEFT]['name']\ .startswith('p10_single') synch.join()
def test_location_cache(loop, monkeypatch, get_labware_def): hardware = API.build_hardware_simulator(loop=loop) ctx = papi.ProtocolContext(loop) ctx.connect(hardware) right = ctx.load_instrument('p10_single', Mount.RIGHT) lw = ctx.load_labware('corning_96_wellplate_360ul_flat', 1) ctx.home() test_args = None def fake_plan_move(from_loc, to_loc, deck, well_z_margin=None, lw_z_margin=None, force_direct=False, minimum_z_height=None): nonlocal test_args test_args = (from_loc, to_loc, deck, well_z_margin, lw_z_margin) return [(Point(0, 1, 10), None), (Point(1, 2, 10), None), (Point(1, 2, 3), None)] monkeypatch.setattr(papi.geometry, 'plan_moves', fake_plan_move) # When we move without a cache, the from location should be the gantry # position right.move_to(lw.wells()[0].top()) # The home position from hardware_control/simulator.py, taking into account # that the right pipette is a p10 single which is a different height than # the reference p300 single assert test_args[0].point == Point(418, 353, 205) assert test_args[0].labware is None # Once we have a location cache, that should be our from_loc right.move_to(lw.wells()[1].top()) assert test_args[0].labware == lw.wells()[0]
def test_hw_manager(loop): # When built without an input it should build its own adapter mgr = papi.ProtocolContext.HardwareManager(None) assert mgr._is_orig adapter = mgr.hardware # When "disconnecting" from its own simulator, the adapter should # be stopped and a new one created assert adapter.is_alive() new = mgr.reset_hw() assert new is not adapter assert not adapter.is_alive() # When deleted, the self-created adapter should be stopped del mgr assert not new.is_alive() # When built with a hardware API input it should wrap it but not # build its own mgr = papi.ProtocolContext.HardwareManager( API.build_hardware_simulator(loop=loop)) assert isinstance(mgr.hardware, adapters.SynchronousAdapter) assert not mgr._is_orig passed = mgr.hardware # When disconnecting from a real external adapter, it should create # its own simulator and should _not_ stop the old hardware thread new = mgr.reset_hw() assert new is not passed assert mgr._is_orig assert passed.is_alive() # When connecting to an adapter it shouldn’t rewrap it assert mgr.set_hw(passed) is passed # And should kill its old one assert not new.is_alive() del mgr # but not its new one, even if deleted assert passed.is_alive()
async def test_get_bundled_fw(monkeypatch, tmpdir): from opentrons.hardware_control import modules dummy_td_file = Path(tmpdir) / '*****@*****.**' dummy_td_file.write_text("hello") dummy_md_file = Path(tmpdir) / '*****@*****.**' dummy_md_file.write_text("hello") dummy_tc_file = Path(tmpdir) / '*****@*****.**' dummy_tc_file.write_text("hello") dummy_bogus_file = Path(tmpdir) / '*****@*****.**' dummy_bogus_file.write_text("hello") monkeypatch.setattr(modules.mod_abc, 'ROBOT_FIRMWARE_DIR', Path(tmpdir)) monkeypatch.setattr(modules.mod_abc, 'IS_ROBOT', True) from opentrons.hardware_control import API mods = ['tempdeck', 'magdeck', 'thermocycler'] api = API.build_hardware_simulator(attached_modules=mods) await asyncio.sleep(0.05) assert api.attached_modules[0].bundled_fw == BundledFirmware( version='1.2.3', path=dummy_td_file) assert api.attached_modules[1].bundled_fw == BundledFirmware( version='3.2.1', path=dummy_md_file) assert api.attached_modules[2].bundled_fw == BundledFirmware( version='0.1.2', path=dummy_tc_file)
async def test_motion(loop): hardware = API.build_hardware_simulator(loop=loop) ctx = papi.ProtocolContext(loop) ctx.connect(hardware) ctx.home() instr = ctx.load_instrument('p10_single', Mount.RIGHT) old_pos = await hardware.current_position(instr._mount) instr.home() assert instr.move_to(Location(Point(0, 0, 0), None)) is instr old_pos[Axis.X] = 0 old_pos[Axis.Y] = 0 old_pos[Axis.A] = 0 old_pos[Axis.C] = 2 assert await hardware.current_position(instr._mount) == old_pos
def test_move_uses_arc(loop, monkeypatch, get_labware_def): hardware = API.build_hardware_simulator(loop=loop) ctx = papi.ProtocolContext(loop) ctx.connect(hardware) ctx.home() right = ctx.load_instrument('p10_single', Mount.RIGHT) lw = ctx.load_labware('corning_96_wellplate_360ul_flat', 1) ctx.home() targets = [] async def fake_move(mount, target_pos, **kwargs): nonlocal targets targets.append((mount, target_pos, kwargs)) monkeypatch.setattr(hardware, 'move_to', fake_move) right.move_to(lw.wells()[0].top()) assert len(targets) == 3 assert targets[-1][0] == Mount.RIGHT assert targets[-1][1] == lw.wells()[0].top().point
def test_hw_manager(loop): # When built without an input it should build its own adapter mgr = HardwareManager(None) assert mgr._is_orig assert mgr._built_own_adapter adapter = mgr.hardware # When "disconnecting" from its own simulator, the adapter should # be stopped and a new one created assert adapter.is_alive() new = mgr.reset_hw() assert new is not adapter assert not adapter.is_alive() # When deleted, the self-created adapter should be stopped del mgr assert not new.is_alive() # When built with a hardware API input it should wrap it with a new # synchronous adapter and not build its own API mgr = HardwareManager(API.build_hardware_simulator(loop=loop)) assert isinstance(mgr.hardware, adapters.SynchronousAdapter) assert not mgr._is_orig assert mgr._built_own_adapter passed = mgr.hardware # When disconnecting from a real external adapter, it should create # its own simulator and should stop the old hardware thread new = mgr.reset_hw() assert new is not passed assert mgr._is_orig assert mgr._built_own_adapter assert not passed.is_alive() sa = adapters.SynchronousAdapter.build(API.build_hardware_simulator) # When connecting to an adapter it shouldn’t rewrap it assert mgr.set_hw(sa) is sa # And should kill its old one assert not new.is_alive() # it should know it didn't build its own adapter assert not mgr._built_own_adapter del mgr # but not its new one, even if deleted assert sa.is_alive()
async def test_max_speeds(loop, monkeypatch): hardware = API.build_hardware_simulator(loop=loop) ctx = papi.ProtocolContext(loop) ctx.connect(hardware) ctx.home() mock_move = mock.Mock() monkeypatch.setattr(ctx._hw_manager.hardware, 'move_to', mock_move) instr = ctx.load_instrument('p10_single', Mount.RIGHT) instr.move_to(Location(Point(0, 0, 0), None)) assert all(kwargs['max_speeds'] == {} for args, kwargs in mock_move.call_args_list) mock_move.reset_mock() ctx.max_speeds['x'] = 10 instr.move_to(Location(Point(0, 0, 1), None)) assert all(kwargs['max_speeds'] == {Axis.X: 10} for args, kwargs in mock_move.call_args_list) mock_move.reset_mock() ctx.max_speeds['x'] = None instr.move_to(Location(Point(1, 0, 1), None)) assert all(kwargs['max_speeds'] == {} for args, kwargs in mock_move.call_args_list)
def hardware_api(loop): hw_api = API.build_hardware_simulator(loop=loop) return hw_api