Plesty Documentation

CompositeDevice Pattern

Group multiple device clients under a single named container for experiment use.

CompositeDevice (from plesty.lib.device.composite_device) is a lightweight container that holds named device clients or local device instances. It gives experiments a clean way to manage multiple instruments without manual lifecycle coordination.

Constructor

from plesty.lib.device.composite_device import CompositeDevice
from plesty.lib.service import build_client

# Build clients to remote device servers
laser = build_client("tcp://laser-host:5555")
powermeter = build_client("tcp://pm-host:5556")

# Group them under meaningful names
instruments = CompositeDevice({
    "laser": laser,
    "powermeter": powermeter,
})

After construction, each device is accessible as an attribute:

# Identical to calling powermeter.query("POWER") directly
power = instruments.powermeter.query("POWER")

# Set laser wavelength
instruments.laser.write("WAVELENGTH", 1064)

Context manager

CompositeDevice supports the context manager protocol. On __enter__, it calls connect() on any local BaseDeviceSyncModel instances (TCP clients manage their own connection). On __exit__, it calls disconnect() on all of them:

with CompositeDevice({"laser": laser, "powermeter": powermeter}) as instruments:
    instruments.laser.write("WAVELENGTH", 1064)
    power = instruments.powermeter.query("POWER")

Note: connect_all() / disconnect_all() only call connect() / disconnect() on BaseDeviceSyncModel instances — TCP clients (DeviceTCPIPClient) manage their own connection lifecycle.

Identity check

identities = instruments.identity()
# Returns: {"laser": "COHERENT,OBIS,v1.2.0", "powermeter": "Thorlabs PM100D,..."}

identity() calls identity() on every sub-device and returns a mapping. Exceptions are caught and reported as strings rather than propagated, so one failing device does not prevent others from being queried.

Accepted device types

CompositeDevice accepts two types of values in the constructor dict:

  • BaseDeviceSyncModel — a local device instance (physical connection managed locally)
  • DeviceTCPIPClient — a TCP client built with build_client()

Any other type raises ValueError at construction time.

Mixed local and remote devices

from plesty.power_meter import PowermeterDevice
from plesty.lib.service import build_client

# Local device (VISA on this machine)
local_pm = PowermeterDevice("USB0::0x1313::0x8078::P0000001::INSTR")

# Remote device (on another machine)
remote_laser = build_client("tcp://laser-host:5555")

instruments = CompositeDevice({
    "powermeter": local_pm,
    "laser": remote_laser,
})