Devices#

In EOS, a device is an abstraction for a physical or virtual apparatus. A device is used by one or more tasks to run some processes. Each device in EOS is managed by a dedicated process which is created when a laboratory definition is loaded. This process is usually implemented as a server and tasks call various functions from it. For example, there could be a device called “magnetic mixer”, which communicates with a physical magnetic mixer via serial and provides functions such as start, stop, set_time and set_speed.

EOS Tasks and Devices

In the figure above, we illustrate an example of devices and a task that uses these devices. The task in this example is Gas Chromatography (GC) sampling, which is implemented with a GC and a mobile manipulation robot for automating the sample injection with a syringe. Both the GC and the robot are physical devices, and each has a device implementation in EOS, which runs as a persistent process. Then, the GC Sampling task uses both of the EOS devices to automate the sample injection process.

Most often, an EOS device will represent a physical device in the lab. But this need not always be the case. A device in EOS can be used to represent anything that needs persistent state throughout one or more experiments. This could be an AI module that records inputs given to it. Remember that a device in EOS is a persistent process.

Device Implementation#

  • Devices are implemented in the devices subdirectory inside an EOS package

  • Each device has its own subfolder (e.g., devices/magnetic_mixer)

  • There are two key files per device: device.yml and device.py

YAML File (device.yml)#

  • Specifies the device type, description, and initialization parameters

  • The same implementation can be used for multiple devices of the same type

  • Initialization parameters can be overridden in laboratory definition

Below is an example device YAML file for a magnetic mixer:

device.yml

type: magnetic_mixer
description: Magnetic mixer for mixing the contents of a container

initialization_parameters:
  port: 5004

Python File (device.py)#

  • Implements device functionality

  • All devices implementations must inherit from BaseDevice

  • The device class name must end with “Device” to be discovered by EOS

Below is a example implementation of a magnetic mixer device:

device.py

from typing import Dict, Any

from eos.containers.entities.container import Container
from eos.devices.base_device import BaseDevice
from user.color_lab.common.device_client import DeviceClient

class MagneticMixerDevice(BaseDevice):
    async def _initialize(self, initialization_parameters: Dict[str, Any]) -> None:
        port = int(initialization_parameters["port"])
        self.client = DeviceClient(port)
        self.client.open_connection()

    async def _cleanup(self) -> None:
        self.client.close_connection()

    async def _report(self) -> Dict[str, Any]:
        return {}

    def mix(self, container: Container, mixing_time: int, mixing_speed: int) -> Container:
        result = self.client.send_command("mix", {"mixing_time": mixing_time, "mixing_speed": mixing_speed})
        if result:
            container.metadata["mixing_time"] = mixing_time
            container.metadata["mixing_speed"] = mixing_speed

        return container

Let’s walk through this example code:

There are functions required in every device implementation:

  1. _initialize

    • Called when device process is created

    • Should set up necessary resources (e.g., serial connections)

  2. _cleanup

    • Called when the device process is terminated

    • Should clean up any resources created by the device process (e.g., serial connections)

  3. _report

    • Should return any data needed to determine the state of the device (e.g., status and feedback)

The magnetic mixer device also has the function mix for implementing the mixing operation. This function will be called by a task to mix the contents of a container. The mix function:

  • Sends a command to lower-level driver with a specified mixing time and speed to operate the magnetic mixer

  • Updates container metadata with mixing details