Skip to content

Commit

Permalink
feat(robot-server): show module compatibility
Browse files Browse the repository at this point in the history
The robot server's /modules endpoint now has a compatibleWithRobot field
that shows whether the connected module is considered compatible with
the robot it's running on.

That compatibility determination is based on the deck name for
now (module model definitions list what deck names they're compatible
with) though we might want to change it to the reverse, listing in the
deck configuration which modules are compatible with this deck.

Closes RSQ-6
  • Loading branch information
sfoster1 committed May 14, 2024
1 parent 35f7bd4 commit 90dc748
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 19 deletions.
14 changes: 13 additions & 1 deletion robot-server/robot_server/modules/module_data_mapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
"""Module identification and response data mapping."""
from typing import Type, cast, Optional
from fastapi import Depends

from opentrons_shared_data.module import load_definition

from opentrons.hardware_control.modules import (
LiveData,
Expand All @@ -16,7 +19,7 @@
)
from opentrons.drivers.rpi_drivers.types import USBPort as HardwareUSBPort

from opentrons.protocol_engine import ModuleModel
from opentrons.protocol_engine import ModuleModel, DeckType

from .module_identifier import ModuleIdentity
from .module_models import (
Expand All @@ -34,10 +37,15 @@
UsbPort,
)

from robot_server.hardware import get_deck_type


class ModuleDataMapper:
"""Map hardware control modules to module response."""

def __init__(self, deck_type: DeckType = Depends(get_deck_type)) -> None:
self.deck_type = deck_type

def map_data(
self,
model: str,
Expand All @@ -53,6 +61,7 @@ def map_data(

module_cls: Type[AttachedModule]
module_data: AttachedModuleData
module_definition = load_definition(model_or_loadname=model, version="3")

# rely on Pydantic to check/coerce data fields from dicts at run time
if module_type == ModuleType.MAGNETIC:
Expand Down Expand Up @@ -131,6 +140,9 @@ def map_data(
firmwareVersion=module_identity.firmware_version,
hardwareRevision=module_identity.hardware_revision,
hasAvailableUpdate=has_available_update,
compatibleWithRobot=(
not (self.deck_type.value in module_definition["incompatibleWithDecks"])
),
usbPort=UsbPort(
port=usb_port.port_number,
portGroup=usb_port.port_group,
Expand Down
3 changes: 3 additions & 0 deletions robot-server/robot_server/modules/module_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class _GenericModule(GenericModel, Generic[ModuleT, ModuleModelT, ModuleDataT]):
moduleOffset: Optional[ModuleCalibrationData] = Field(
None, description="The calibrated module offset."
)
compatibleWithRobot: bool = Field(
..., description="Whether the detected module is compatible with this robot."
)
data: ModuleDataT
usbPort: UsbPort

Expand Down
99 changes: 98 additions & 1 deletion robot-server/tests/integration/test_modules.tavern.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
test_name: Get modules
test_name: Get modules OT2
marks:
- usefixtures:
- ot2_server_base_url
Expand Down Expand Up @@ -113,6 +113,7 @@ stages:
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: thermocyclerModuleType
moduleModel: thermocyclerModuleV1
usbPort:
Expand All @@ -134,6 +135,7 @@ stages:
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: heaterShakerModuleType
moduleModel: heaterShakerModuleV1
usbPort:
Expand All @@ -153,6 +155,7 @@ stages:
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: temperatureModuleType
moduleModel: temperatureModuleV1
usbPort:
Expand All @@ -169,6 +172,7 @@ stages:
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: magneticModuleType
moduleModel: magneticModuleV2
usbPort:
Expand All @@ -185,6 +189,7 @@ stages:
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: magneticModuleType
moduleModel: magneticModuleV1
usbPort:
Expand All @@ -196,3 +201,95 @@ stages:
status: !anystr
height: !anyfloat
engaged: !anybool

---
test_name: Get modules on Flex
marks:
- usefixtures:
- ot3_server_base_url
stages:
- name: Get all the modules
request:
url: '{ot3_server_base_url}/modules'
method: GET
response:
status_code: 200
json:
meta: !anydict
data:
- id: !anystr
serialNumber: !anystr
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: thermocyclerModuleType
moduleModel: thermocyclerModuleV2
usbPort:
port: !anyint
hub: !anybool
portGroup: !anystr
path: !anystr
data:
status: !anystr
lidStatus: !anystr
lidTemperatureStatus: !anystr
lidTargetTemperature: !anyfloat
lidTemperature: !anyfloat
currentTemperature: !anyfloat
targetTemperature: !anyfloat
holdTime: !anyfloat
- id: !anystr
serialNumber: !anystr
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: heaterShakerModuleType
moduleModel: heaterShakerModuleV1
usbPort:
port: !anyint
hub: !anybool
portGroup: !anystr
path: !anystr
data:
status: !anystr
labwareLatchStatus: !anystr
speedStatus: !anystr
temperatureStatus: !anystr
currentSpeed: !anyint
currentTemperature: !anyfloat
- id: !anystr
serialNumber: !anystr
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: temperatureModuleType
moduleModel: temperatureModuleV2
usbPort:
port: !anyint
hub: !anybool
portGroup: !anystr
path: !anystr
data:
status: !anystr
currentTemperature: !anyfloat
targetTemperature: !anyfloat
- id: !anystr
serialNumber: !anystr
firmwareVersion: !anystr
hardwareRevision: !anystr
hasAvailableUpdate: !anybool
compatibleWithRobot: true
moduleType: temperatureModuleType
moduleModel: temperatureModuleV2
usbPort:
port: !anyint
hub: !anybool
portGroup: !anystr
path: !anystr
data:
status: !anystr
currentTemperature: !anyfloat
targetTemperature: !anyfloat
Loading

0 comments on commit 90dc748

Please sign in to comment.