diff --git a/api/src/opentrons/drivers/heater_shaker/simulator.py b/api/src/opentrons/drivers/heater_shaker/simulator.py index ae90bc33027..8844d069cfa 100644 --- a/api/src/opentrons/drivers/heater_shaker/simulator.py +++ b/api/src/opentrons/drivers/heater_shaker/simulator.py @@ -1,4 +1,4 @@ -from typing import Dict +from typing import Dict, Optional from opentrons.util.async_helpers import ensure_yield from opentrons.drivers.heater_shaker.abstract import AbstractHeaterShakerDriver from opentrons.drivers.types import Temperature, RPM, HeaterShakerLabwareLatchStatus @@ -7,12 +7,13 @@ class SimulatingDriver(AbstractHeaterShakerDriver): DEFAULT_TEMP = 23 - def __init__(self) -> None: + def __init__(self, serial_number: Optional[str] = None) -> None: self._labware_latch_state = HeaterShakerLabwareLatchStatus.IDLE_UNKNOWN self._current_temperature = self.DEFAULT_TEMP self._temperature = Temperature(current=self.DEFAULT_TEMP, target=None) self._rpm = RPM(current=0, target=None) self._homing_status = True + self._serial_number = serial_number @ensure_yield async def connect(self) -> None: @@ -83,7 +84,7 @@ async def deactivate(self) -> None: @ensure_yield async def get_device_info(self) -> Dict[str, str]: return { - "serial": "dummySerialHS", + "serial": self._serial_number if self._serial_number else "dummySerialHS", "model": "dummyModelHS", "version": "dummyVersionHS", } diff --git a/api/src/opentrons/drivers/mag_deck/simulator.py b/api/src/opentrons/drivers/mag_deck/simulator.py index 1b8bc545bf4..303711ce6c2 100644 --- a/api/src/opentrons/drivers/mag_deck/simulator.py +++ b/api/src/opentrons/drivers/mag_deck/simulator.py @@ -11,9 +11,12 @@ class SimulatingDriver(AbstractMagDeckDriver): - def __init__(self, sim_model: Optional[str] = None) -> None: + def __init__( + self, sim_model: Optional[str] = None, serial_number: Optional[str] = None + ) -> None: self._height = 0.0 self._model = MAG_DECK_MODELS[sim_model] if sim_model else "mag_deck_v1.1" + self._serial_number = serial_number @ensure_yield async def probe_plate(self) -> None: @@ -30,7 +33,7 @@ async def move(self, location: float) -> None: @ensure_yield async def get_device_info(self) -> Dict[str, str]: return { - "serial": "dummySerialMD", + "serial": self._serial_number if self._serial_number else "dummySerialMD", "model": self._model, "version": "dummyVersionMD", } diff --git a/api/src/opentrons/drivers/temp_deck/simulator.py b/api/src/opentrons/drivers/temp_deck/simulator.py index efce88ea234..09a4f791e01 100644 --- a/api/src/opentrons/drivers/temp_deck/simulator.py +++ b/api/src/opentrons/drivers/temp_deck/simulator.py @@ -11,10 +11,13 @@ class SimulatingDriver(AbstractTempDeckDriver): - def __init__(self, sim_model: Optional[str] = None): + def __init__( + self, sim_model: Optional[str] = None, serial_number: Optional[str] = None + ): self._temp = Temperature(target=None, current=0) self._port: Optional[str] = None self._model = TEMP_DECK_MODELS[sim_model] if sim_model else "temp_deck_v1.1" + self._serial_number = serial_number @ensure_yield async def set_temperature(self, celsius: float) -> None: @@ -48,7 +51,7 @@ async def enter_programming_mode(self) -> None: @ensure_yield async def get_device_info(self) -> Dict[str, str]: return { - "serial": "dummySerialTD", + "serial": self._serial_number if self._serial_number else "dummySerialTD", "model": self._model, "version": "dummyVersionTD", } diff --git a/api/src/opentrons/drivers/thermocycler/simulator.py b/api/src/opentrons/drivers/thermocycler/simulator.py index 4a92bb12587..302391a988d 100644 --- a/api/src/opentrons/drivers/thermocycler/simulator.py +++ b/api/src/opentrons/drivers/thermocycler/simulator.py @@ -10,7 +10,9 @@ class SimulatingDriver(AbstractThermocyclerDriver): DEFAULT_TEMP = 23 - def __init__(self, model: Optional[str] = None) -> None: + def __init__( + self, model: Optional[str] = None, serial_number: Optional[str] = None + ) -> None: self._ramp_rate: Optional[float] = None self._lid_status = ThermocyclerLidStatus.OPEN self._lid_temperature = Temperature(current=self.DEFAULT_TEMP, target=None) @@ -18,6 +20,7 @@ def __init__(self, model: Optional[str] = None) -> None: current=self.DEFAULT_TEMP, target=None, hold=None ) self._model = model if model else "thermocyclerModuleV1" + self._serial_number = serial_number def model(self) -> str: return self._model @@ -103,7 +106,7 @@ async def deactivate_all(self) -> None: @ensure_yield async def get_device_info(self) -> Dict[str, str]: return { - "serial": "dummySerialTC", + "serial": self._serial_number if self._serial_number else "dummySerialTC", "model": "dummyModelTC", "version": "dummyVersionTC", } diff --git a/api/src/opentrons/hardware_control/module_control.py b/api/src/opentrons/hardware_control/module_control.py index 41d9860aac7..254885000ee 100644 --- a/api/src/opentrons/hardware_control/module_control.py +++ b/api/src/opentrons/hardware_control/module_control.py @@ -15,6 +15,8 @@ save_module_calibration_offset, ) from opentrons.hardware_control.modules.types import ModuleType +from opentrons.hardware_control.modules import SimulatingModuleAtPort + from opentrons.types import Point from .types import AionotifyEvent, BoardRevision, OT3Mount from . import modules @@ -84,6 +86,7 @@ async def build_module( usb_port: types.USBPort, type: modules.ModuleType, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> modules.AbstractModule: return await modules.build( port=port, @@ -93,6 +96,7 @@ async def build_module( hw_control_loop=self._api.loop, execution_manager=self._api._execution_manager, sim_model=sim_model, + serial_number=serial_number, ) async def unregister_modules( @@ -154,6 +158,9 @@ async def register_modules( port=mod.port, usb_port=mod.usb_port, type=modules.MODULE_TYPE_BY_NAME[mod.name], + serial_number=mod.serial_number + if isinstance(mod, SimulatingModuleAtPort) + else None, ) self._available_modules.append(new_instance) log.info( diff --git a/api/src/opentrons/hardware_control/modules/heater_shaker.py b/api/src/opentrons/hardware_control/modules/heater_shaker.py index d4a8fb11d94..df23c2e8ef5 100644 --- a/api/src/opentrons/hardware_control/modules/heater_shaker.py +++ b/api/src/opentrons/hardware_control/modules/heater_shaker.py @@ -49,6 +49,7 @@ async def build( poll_interval_seconds: Optional[float] = None, simulating: bool = False, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> "HeaterShaker": """ Build a HeaterShaker @@ -71,7 +72,7 @@ async def build( driver = await HeaterShakerDriver.create(port=port, loop=hw_control_loop) poll_interval_seconds = poll_interval_seconds or POLL_PERIOD else: - driver = SimulatingDriver() + driver = SimulatingDriver(serial_number=serial_number) poll_interval_seconds = poll_interval_seconds or SIMULATING_POLL_PERIOD reader = HeaterShakerReader(driver=driver) diff --git a/api/src/opentrons/hardware_control/modules/magdeck.py b/api/src/opentrons/hardware_control/modules/magdeck.py index e195716882a..7f0293485f3 100644 --- a/api/src/opentrons/hardware_control/modules/magdeck.py +++ b/api/src/opentrons/hardware_control/modules/magdeck.py @@ -53,13 +53,14 @@ async def build( poll_interval_seconds: Optional[float] = None, simulating: bool = False, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> "MagDeck": """Factory function.""" driver: AbstractMagDeckDriver if not simulating: driver = await MagDeckDriver.create(port=port, loop=hw_control_loop) else: - driver = SimulatingDriver(sim_model=sim_model) + driver = SimulatingDriver(sim_model=sim_model, serial_number=serial_number) mod = cls( port=port, diff --git a/api/src/opentrons/hardware_control/modules/mod_abc.py b/api/src/opentrons/hardware_control/modules/mod_abc.py index 48d7f79e4b2..72b6b47969e 100644 --- a/api/src/opentrons/hardware_control/modules/mod_abc.py +++ b/api/src/opentrons/hardware_control/modules/mod_abc.py @@ -32,6 +32,7 @@ async def build( poll_interval_seconds: Optional[float] = None, simulating: bool = False, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> "AbstractModule": """Modules should always be created using this factory. diff --git a/api/src/opentrons/hardware_control/modules/tempdeck.py b/api/src/opentrons/hardware_control/modules/tempdeck.py index 261d40ea026..1fb4ad3a64e 100644 --- a/api/src/opentrons/hardware_control/modules/tempdeck.py +++ b/api/src/opentrons/hardware_control/modules/tempdeck.py @@ -39,6 +39,7 @@ async def build( poll_interval_seconds: Optional[float] = None, simulating: bool = False, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> "TempDeck": """ Build a TempDeck @@ -60,7 +61,7 @@ async def build( driver = await TempDeckDriver.create(port=port, loop=hw_control_loop) poll_interval_seconds = poll_interval_seconds or TEMP_POLL_INTERVAL_SECS else: - driver = SimulatingDriver(sim_model=sim_model) + driver = SimulatingDriver(sim_model=sim_model, serial_number=serial_number) poll_interval_seconds = poll_interval_seconds or SIM_TEMP_POLL_INTERVAL_SECS reader = TempDeckReader(driver=driver) diff --git a/api/src/opentrons/hardware_control/modules/thermocycler.py b/api/src/opentrons/hardware_control/modules/thermocycler.py index fe333d37849..04242b8555d 100644 --- a/api/src/opentrons/hardware_control/modules/thermocycler.py +++ b/api/src/opentrons/hardware_control/modules/thermocycler.py @@ -63,6 +63,7 @@ async def build( poll_interval_seconds: Optional[float] = None, simulating: bool = False, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> "Thermocycler": """ Build and connect to a Thermocycler @@ -87,7 +88,7 @@ async def build( ) poll_interval_seconds = poll_interval_seconds or POLLING_FREQUENCY_SEC else: - driver = SimulatingDriver(model=sim_model) + driver = SimulatingDriver(model=sim_model, serial_number=serial_number) poll_interval_seconds = poll_interval_seconds or SIM_POLLING_FREQUENCY_SEC reader = ThermocyclerReader(driver=driver) diff --git a/api/src/opentrons/hardware_control/modules/types.py b/api/src/opentrons/hardware_control/modules/types.py index 7c79f5b0e30..432848ca32b 100644 --- a/api/src/opentrons/hardware_control/modules/types.py +++ b/api/src/opentrons/hardware_control/modules/types.py @@ -111,7 +111,7 @@ class ModuleAtPort: class SimulatingModuleAtPort(ModuleAtPort): - serial_numer: str + serial_number: str class BundledFirmware(NamedTuple): diff --git a/api/src/opentrons/hardware_control/modules/utils.py b/api/src/opentrons/hardware_control/modules/utils.py index 56a47f977da..557c2c4bbf8 100644 --- a/api/src/opentrons/hardware_control/modules/utils.py +++ b/api/src/opentrons/hardware_control/modules/utils.py @@ -42,6 +42,7 @@ async def build( hw_control_loop: asyncio.AbstractEventLoop, execution_manager: ExecutionManager, sim_model: Optional[str] = None, + serial_number: Optional[str] = None, ) -> AbstractModule: return await _MODULE_CLS_BY_TYPE[type].build( port=port, @@ -50,6 +51,7 @@ async def build( hw_control_loop=hw_control_loop, execution_manager=execution_manager, sim_model=sim_model, + serial_number=serial_number, )