Skip to content

Commit

Permalink
feat(api): add instrument cache to hardware control
Browse files Browse the repository at this point in the history
Closes #2236
  • Loading branch information
sanni-t committed Oct 2, 2018
1 parent 0202b53 commit 6866aff
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 12 deletions.
16 changes: 12 additions & 4 deletions api/opentrons/hardware_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ def __init__(self,
# {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'A': 0.0, 'B': 0.0, 'C': 0.0}
self._current_position: dict = None

self._attached_instruments = {types.Mount.LEFT: None,
types.Mount.RIGHT: None}

@classmethod
def build_hardware_controller(
cls, config: dict = None,
Expand All @@ -101,14 +104,16 @@ def build_hardware_controller(

@classmethod
def build_hardware_simulator(
cls, config: dict = None,
cls,
attached_instruments,
config: dict = None,
loop: asyncio.AbstractEventLoop = None) -> 'API':
""" Build a simulating hardware controller.
This method may be used both on a real robot and on dev machines.
Multiple simulating hardware controllers may be active at one time.
"""
return cls(simulator.Simulator(config, loop),
return cls(simulator.Simulator(attached_instruments, config, loop),
config=config, loop=loop)

# Query API
Expand Down Expand Up @@ -141,7 +146,10 @@ async def identify(self, seconds):

@_log_call
async def cache_instrument_models(self):
pass
self._log.info("Updating instrument model cache")
for mount in types.Mount:
self._attached_instruments[mount] = \
self._backend.get_attached_instruments(mount)

@_log_call
async def update_smoothie_firmware(self, firmware_file):
Expand Down Expand Up @@ -203,7 +211,7 @@ async def _move(self, target_position: Dict[str, float]):
try:
self._backend.move(target_position)
except Exception:
mod_log.exception('Move failed')
self._log.exception('Move failed')
self._current_position.clear()
raise

Expand Down
3 changes: 3 additions & 0 deletions api/opentrons/hardware_control/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,6 @@ def move(self, target_position: Dict[str, float], home_flagged_axes=True):

def home(self):
return self._smoothie_driver.home()

def get_attached_instruments(self, mount):
return self._smoothie_driver.read_pipette_model(mount.name.lower())
6 changes: 5 additions & 1 deletion api/opentrons/hardware_control/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ class Simulator:
a robot with no smoothie connected.
"""

def __init__(self, config, loop):
def __init__(self, attached_instruments, config, loop):
self._config = config
self._loop = loop
self._attached_instruments = attached_instruments

def move(self, target_position: Dict[str, float]):
pass

def home(self):
# driver_3_0-> HOMED_POSITION
return {'X': 418, 'Y': 353, 'Z': 218, 'A': 218, 'B': 19, 'C': 19}

def get_attached_instruments(self, mount):
return self._attached_instruments[mount]
30 changes: 30 additions & 0 deletions api/tests/opentrons/hardware_control/test_instruments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest
from opentrons import types
from opentrons import hardware_control as hc


async def test_cache_instruments(loop):
dummy_instruments_attached = {types.Mount.LEFT: 'model_abc',
types.Mount.RIGHT: None}
hw_api = hc.API.build_hardware_simulator(
attached_instruments=dummy_instruments_attached, loop=loop)
await hw_api.cache_instrument_models()
assert hw_api._attached_instruments == dummy_instruments_attached


@pytest.mark.skipif(not hc.controller,
reason='hardware controller not available '
'(probably windows)')
async def test_cache_instruments_hc(monkeypatch, hardware_controller_lockfile,
running_on_pi, loop):
dummy_instruments_attached = {types.Mount.LEFT: 'model_abc',
types.Mount.RIGHT: None}
hw_api_cntrlr = hc.API.build_hardware_controller(loop=loop)

def mock_driver_method(mount):
attached_pipette = {'left': 'model_abc', 'right': None}
return attached_pipette[mount]
monkeypatch.setattr(hw_api_cntrlr._backend._smoothie_driver,
'read_pipette_model', mock_driver_method)
await hw_api_cntrlr.cache_instrument_models()
assert hw_api_cntrlr._attached_instruments == dummy_instruments_attached
13 changes: 6 additions & 7 deletions api/tests/opentrons/hardware_control/test_moves.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@
from opentrons import types
from opentrons import hardware_control as hc

if not hc.controller:
pytest.skip('hardware controller not available (probably windows)',
allow_module_level=True)


@pytest.fixture
def hardware_api(monkeypatch, loop):
def mock_move(position):
pass

hw_api = hc.API.build_hardware_simulator(loop=loop)
attached_pipettes = {types.Mount.LEFT: None, types.Mount.RIGHT: None}
hw_api = hc.API.build_hardware_simulator(
attached_instruments=attached_pipettes, loop=loop)
monkeypatch.setattr(hw_api._backend, 'move', mock_move)
return hw_api


async def test_controller_home(loop):
c = hc.API.build_hardware_simulator(loop=loop)
attached_pipettes = {types.Mount.LEFT: None, types.Mount.RIGHT: None}
c = hc.API.build_hardware_simulator(
attached_instruments=attached_pipettes, loop=loop)
await c.home()
assert c._current_position == {'X': 418, 'Y': 353, 'Z': 218,
'A': 218, 'B': 19, 'C': 19}
Expand Down

0 comments on commit 6866aff

Please sign in to comment.