Plesty Documentation

Parameter and Operation Schemas

Define device capabilities in param_schema.json and op_schema.json.

PLESTY devices define their capabilities in two JSON schema files. These schemas are the source of truth for parameter validation, documentation generation, and test automation.

param_schema.json

Defines all readable/writable device parameters.

Flat schema (simple devices)

{
  "WAVELENGTH": {
    "type": "int",
    "command": "SENS:CORR:WAV",
    "unit": "nm",
    "min": 400,
    "max": 1700,
    "description": "Measurement wavelength in nm"
  },
  "POWER": {
    "type": "float",
    "command": "MEAS:SCAL:POW",
    "unit": "watt",
    "read_only": true,
    "description": "Measured optical power"
  },
  "AUTO_RANGE": {
    "type": "bool",
    "command": "SENS:POW:RANG:AUTO",
    "default": true,
    "description": "Enable auto-range mode"
  },
  "AVERAGES": {
    "type": "int",
    "command": "SENS:AVER:COUN",
    "min": 1,
    "max": 1000,
    "default": 100,
    "description": "Number of averages per measurement"
  }
}

Grouped schema (multi-channel devices)

{
  "Channel1": {
    "command_prefix": "CH1",
    "parameters": {
      "POWER": {
        "type": "float",
        "command": "MEAS:POW",
        "unit": "watt",
        "read_only": true
      },
      "WAVELENGTH": {
        "type": "int",
        "command": "SENS:WAV",
        "unit": "nm"
      }
    }
  }
}

Grouped parameters resolve to keys like CH1.POWER and CH1.WAVELENGTH.

Supported fields

Field Required Type Description
type yes string One of: int, float, str, bool
command yes string Protocol command string
unit no string Physical unit label
min no number Minimum allowed value
max no number Maximum allowed value
options no array Allowed categorical values
default no any Default value
read_only no bool If true, write raises an error
write_only no bool If true, query raises an error
description no string Human-readable description

op_schema.json

Defines device operations (functions with inputs and outputs beyond simple param read/write).

{
  "measure_power_sequence": {
    "iparams": {
      "count": {
        "type": "int",
        "description": "Number of measurements to take"
      },
      "delay_ms": {
        "type": "float",
        "description": "Delay between measurements in milliseconds"
      }
    },
    "oparams": {
      "powers": {
        "type": "float",
        "description": "Array of measured power values in watts"
      },
      "timestamps": {
        "type": "float",
        "description": "Unix timestamps for each measurement"
      }
    },
    "description": "Take a sequence of power measurements with a fixed delay"
  }
}

Each operation has iparams (inputs) and oparams (outputs). Gate d1's test_funcs_mock verifies that all registered operations return a dict with the correct output keys.

Loading schemas in the device class

The simplest way is to pass the schema path to the base class constructor:

from plesty.lib.device.base_device_sync import BaseDeviceSyncModel

class MyDevice(BaseDeviceSyncModel):
    def __init__(self, address: str):
        super().__init__(
            id=address,
            param_schema="assets/param_schema.json",
            op_schema="assets/op_schema.json",
        )

Or register parameters in code (useful for dynamic ranges that depend on constructor arguments):

class PowermeterDevice(BaseDeviceSyncModel):
    def __init__(self, address: str, sensor_type: str):
        super().__init__(id=address)
        min_wl, max_wl = SENSOR_RANGES[sensor_type]
        self.register_config("WAVELENGTH", dtype=int, unit="nm",
                             min_value=min_wl, max_value=max_wl,
                             command="SENS:CORR:WAV")

Tip: Prefer schema-driven registration for devices with many parameters — an LLM can generate param_schema.json directly from the vendor manual.