Parameter System#

The parameter system is the metadata and validation layer used by device classes in PlestyLib.

It defines what can be queried or written, validates user input, stores cached values, and supports typed parsing of device responses.

Core implementation: ConfigSystem in plestylib.device.params.

What It Does#

ConfigSystem provides:

  1. Parameter registration through code (register_config) or schema (register_params_from_schema).

  2. Optional grouping of parameters (register_config_group).

  3. Validation for type, range, and categorical options.

  4. Read/write permission flags (read_only, write_only).

  5. Current value cache per parameter (value).

  6. Automatic response casting through AutoResponseParser.

  7. Human-readable summaries (param_summary).

Main Data Structures#

ConfigParameter#

Represents one parameter, including:

  1. name

  2. dtype

  3. default and current value

  4. unit

  5. read_only, write_only

  6. min_value, max_value

  7. options

  8. command (string or Command object)

  9. parser (optional custom response parser)

  10. description

ConfigGroup#

Represents a parameter group with:

  1. Group name

  2. Group parameter dictionary

  3. Optional command prefix

  4. Optional list of group-level allowed commands

  5. Group description

Command#

Command metadata object used in grouped schemas:

  1. name

  2. command # some devices may provide command to query or set parameters in this group

  3. required_params # defines required parameters for the group command

  4. optional_params # defines optional paramters for the group command

  5. mode (write or query)

  6. description

Register Parameters in Code#

from plestylib.device.base_visa_scpi_device import BaseVisaScpiDevice


class PowermeterDevice(BaseVisaScpiDevice):
		def __init__(self, address: str):
				super().__init__(address)

				self.register_config("POWER", dtype=float, unit="watt", read_only=True, command="MEAS:SCAL:POW")
				self.register_config("WAVELENGTH", dtype=int, unit="nm", min_value=400, max_value=1100, command="SENS:CORR:WAV")
				self.register_config("AUTO_RANGE", dtype=bool, default=True, command="SENS:POW:RANG:AUTO")

Register Parameters from Schema#

register_params_from_schema supports loading from a JSON file in the following shape:

{
	"ROSCillatorFrequency": {
		"type": "float",
		"command": "SOUR:ROSC:FREQ",
		"description": "Set or query the frequency of the internal reference oscillator."
	},
	"SyncClockoutValue": {
		"type": "integer",
		"command": "SYNC:VAL",
		"read_only": true
	}
}

Load schema from file path or dictionary:

from plestylib.device.params import ConfigSystem

cfg = ConfigSystem(param_schema="param_schema.json")
# or
# cfg = ConfigSystem(param_schema=schema_dict)

Load schema directly in a base-device constructor (BaseDeviceSyncModel):

from plestylib.device.base_device_sync import BaseDeviceSyncModel


class MyDevice(BaseDeviceSyncModel):
	def __init__(self, id: str, param_schema):
		super().__init__(id=id, param_schema=param_schema)

	def connect(self):
		...

	def disconnect(self):
		...

	def check_errors(self) -> list[str]:
		return []

	def check_operatability(self) -> bool:
		return True

	def _write_(self, key, value) -> bool:
		return True

	def _query_(self, key) -> str:
		return "0"


dev_a = MyDevice(id="dev-1", param_schema="param_schema.json")
# or
# dev_b = MyDevice(id="dev-2", param_schema=schema_dict)

Validation Rules#

Validation happens at registration and at write-time checks.

  1. Type checks: values must match dtype.

  2. Numeric range checks: min_value <= value <= max_value.

  3. Option checks: categorical values must be in options.

  4. Permission checks: cannot write read_only parameters.

Important behavior:

  1. Registration errors raise exceptions.

  2. check_write_config raises on invalid values.

  3. set_config_value attempts auto-casting before range/options validation.

Query/Write Flow Integration#

In synchronized devices, high-level methods in BaseDeviceSyncModel use ConfigSystem as follows:

  1. write(key, value)

  2. check_write_config(key, value) validates the request

  3. Device-specific _write_ sends command to hardware

  4. On success, set_config_value updates cached value

For queries:

  1. query(key)

  2. check_query_config(key) validates access

  3. Device-specific _query_ gets raw response

  4. response_to_target_type parses/casts response

  5. set_config_value stores parsed value

Response Parsing#

By default, AutoResponseParser tries to cast response text to the parameter dtype.

Examples:

  1. "42" -> int

  2. "3.14" -> float

  3. "true"/"1" -> bool (via basic cast helper)

  4. Delimited strings for typed list/tuple annotations

If needed, provide a custom parser in parameter metadata via parser.

Useful API Methods#

  1. register_config(...)

  2. register_config_group(...)

  3. register_params_from_schema(...)

  4. get_config(key, group="default")

  5. get_config_list(group="default")

  6. get_group_list()

  7. set_config_value(key, value)

  8. get_config_value(key)

  9. set_config_min_max(key, min_value, max_value)

  10. param_summary(constraints=True, description=False)

Minimal End-to-End Example#

from plestylib.device.params import ConfigSystem

system = ConfigSystem()

system.register_config(
		key="GAIN",
		dtype=int,
		min_value=1,
		max_value=10,
		default=5,
		command="CONF:GAIN",
)

system.check_write_config("GAIN", 7)
system.set_config_value("GAIN", "7")  # auto-cast to int

print(system.get_config_value("GAIN"))
print(system.param_summary())

Best Practices#

  1. Always set dtype for robust validation and auto-casting.

  2. Prefer explicit min_value and max_value for numeric parameters.

  3. Use options for categorical values.

  4. Keep command strings in parameter metadata so solver logic stays generic.

  5. Use schema-driven registration for larger devices.

  6. Include description and unit fields to improve generated summaries and docs.