Skip to content

Instrument Profiles

An instrument profile is a YAML document that tells galois-edge how to talk to a specific instrument: how to identify it, what commands it supports, what each parameter means, what protocol it speaks. The daemon ships with 130+ profiles for common Keysight, Tektronix, Keithley, R&S, and other gear; you can add your own by dropping YAML files into PROFILE_DIR.

Profiles are loaded at daemon startup and on DeployProfile calls. Each one is matched against *IDN? responses; the first profile whose regex matches is the one that’s used.

instrument:
manufacturer: "Keysight"
model: "34461A"
class: dmm
description: "Truevolt Series Digital Multimeter"
identity:
query: "*IDN?"
patterns:
- "(?:Keysight|Agilent).*34[4-7][0-9][0-9]A"
interfaces:
- type: gpib
default_address: 22
- type: usb
- type: ethernet
port: 5025
settings:
timeout_ms: 5000
terminator: "\n"
opc_query: true
commands:
measure_voltage:
scpi: "MEAS:VOLT:DC?"
type: query
returns:
type: float
unit: V
description: "Measure DC voltage"
set_range:
scpi: "VOLT:DC:RANG {range}"
type: write
params:
range:
type: float
unit: V
options: [0.1, 1, 10, 100, 1000]
default: 10

The top-level keys — instrument, identity, interfaces, settings, commands, sequences, sdk — are described below.

FieldTypeRequiredNotes
manufacturerstringyesUsed by the matched-profile API responses.
modelstringyesCombined with manufacturer to form profile_key (lowercase, underscores).
classstringyesFree-form bucket: dmm, oscilloscope, sourcemeter, network_analyzer, magnet, temperature_controller, … Used by instrument_class filters in the API. The YAML key instrument_class: is also accepted as an alias.
descriptionstringnoHuman-friendly description.

How the daemon recognises this instrument.

FieldTypeRequiredNotes
querystringnoDefault *IDN?.
patternstringone of pattern/patternsSingle regex (case-insensitive).
patternslist[string]one of pattern/patternsMultiple regexes; any match wins. Preferred for instruments with a noisy IDN.

A list of supported physical transports. The daemon uses this to pre-populate addresses (e.g. default GPIB primary address) and to know what serial parameters to apply.

FieldTypeNotes
typestringgpib, usb, ethernet, serial, can.
portintTCP port (LXI/raw socket).
default_addressintGPIB primary address.
baud_rate, parity, data_bits, stop_bitsvariesSerial only.
usb_vid, usb_pidstring (hex)Auto-discovery for serial-over-USB.
busstringCAN bus name — can0, vcan0, etc.
bitrateintCAN bus bitrate (bits/s).
can_protocolstringcan20a, can20b, or canfd.

Communication tuning, applied to every command on this instrument.

FieldTypeDefaultNotes
timeout_msint5000Per-command timeout.
terminatorstring"\n"Line ending.
opc_queryboolfalseSend *OPC? after writes to wait for completion.
init_commandslist[string]emptyRun on first connect (e.g. *RST).
cleanup_commandslist[string]emptyRun on disconnect.

A map of named commands. Each entry follows CommandConfig:

FieldTypeRequiredNotes
scpistringone of scpi/getter/setterTemplate with {param} placeholders.
getter, setterstringfor type: propertyTwo SCPI templates for a read/write property.
typestringyesquery, write, or property.
descriptionstringnoSurfaced in capabilities.
enabledboolno (default true)Set false to hide from clients.
streamableboolnoEligible for StreamMeasurement.
is_dangerousboolnoUI hint.
force_queryboolnoSend the getter as-is, without trailing ?.
requires_sweepboolnoReject ExecuteCommand; require StartSweep.
paramsmap[string, ParameterConfig]noSee below.
returnsReturnConfigfor type: querySee below.
sweepSweepConfigwhen requires_sweepSee below.
sdk_callSDKCallConfigoptionalBind to a vendor SDK method.
canCANCommandConfigoptionalCAN-bus framing.
FieldTypeNotes
typestringfloat, int, string, enum, bool.
unitstringE.g. V, A, Hz.
min, maxfloatRange limits.
defaultanyUsed when caller omits the parameter.
descriptionstring
optionslist[string]Required when type: enum.
mapmap[string, any]Label → wire-value transform applied on writes.
FieldTypeNotes
typestringfloat, int, string, array, binary, bool, vector.
unitstring
element_typestringFor array.
separatorstringFor array (default ,).
formatstringieee_binary or ascii for trace data.
fieldslist[dict]Named multi-value returns.
parserdict{type: regex, pattern, group} / {type: strip, prefix, suffix} / {type: split, delimiter, index}.
x_name, x_unitstringVector axis labels.
x_start_query, x_increment_querystringSCPI to retrieve waveform x-axis metadata.

For commands that ramp over time (magnets, temperature controllers).

FieldTypeNotes
rate_paramstringName of the parameter that controls rate. Defaults to "sweep_rate".
commandstringSCPI template with {value} and {sweep_rate}.
check_commandstringStatus query polled at poll_interval_ms.
check_idle_matchstringExact string or regex meaning “done”.
stop_commandstringEmergency abort SCPI.
poll_interval_msintDefault 1000.

Map a profile command to a method on a Python SDK object.

FieldTypeNotes
methodstringFor ordinary calls.
getter, setterstringWhen is_property: true.
args_mapmap[string, string]Profile param → SDK kwarg.
result_fieldstringPull a field out of a returned dict/object.
is_propertybool

For CAN-bus instruments. Includes message_id, direction (rx/tx/tx_rx), signals (named CANSignalConfig map), response_id (required when direction: tx_rx), payload (fixed request bytes for UDS-style queries), dlc (data length code, 0–64, default 8). Each signal carries start_bit (0–63), bit_length (1–64), byte_order (little_endian/big_endian), signed, scale, offset.

Multi-step measurement recipes that run as a single transaction on the daemon.

sequences:
iv_sweep:
description: "Voltage sweep, capture current at each point"
parameters:
start_v: { type: float, unit: V }
stop_v: { type: float, unit: V }
step_v: { type: float, unit: V }
steps:
- command: set_voltage
args: { value: "{start_v}" }
- scpi: "*WAI"
- command: measure_current
capture: i_first
returns: i_first
FieldTypeNotes
descriptionstring
parametersmap[string, ParameterConfig]The YAML key params: is also accepted as an alias.
stepslist[SequenceStepConfig]Each step references either command (named) or scpi (raw). args populates {} placeholders, capture saves the result under a name. At least one step is required.
returnsstringCaptured variable name to return.
enabledboolDefault true.

Top-level vendor-SDK driver — used for instruments that don’t speak SCPI. Once present, the daemon importlib-loads the package and treats the resulting object as the instrument.

sdk:
package: "MultiPyVu"
import_path: "MultiPyVu"
class_name: "Client"
is_async: false
connect:
method: "connect"
args:
host: "host"
defaults: { host: "127.0.0.1", port: 5000 }
disconnect:
method: "close"
identity:
method: "get_instrument_info"
pattern: "PPMS"
FieldTypeNotes
packagestringPyPI / pip name.
import_pathstringModule path used in importlib.
class_namestringClass to instantiate.
is_asyncboolUse await on calls.
connectSDKConnectConfigmethod to call on first use; args maps profile params to kwargs; defaults fills in missing kwargs; constructor_args is passed to the class constructor before connect runs.
disconnectSDKDisconnectConfigmethod to call on shutdown.
identitySDKIdentityConfigOptional: method or property to read for IDN-equivalent matching, plus pattern regex.

The daemon validates every loaded profile and refuses to register one that fails. Validation errors include:

  • identity defines neither pattern nor patterns, or a regex fails to compile.
  • A command sets none of scpi, getter, setter, sdk_call, or can.
  • A property command has neither getter nor setter.
  • A parameter declares an unknown type (must be one of float, int, string, enum, bool).
  • An enum parameter has no options.
  • A return type is unknown (must be one of float, int, string, array, binary, bool, vector).
  • A sequence has zero steps, or a step has neither command nor scpi.
  • A CAN frame has out-of-range message_id (0..0x1FFFFFFF), dlc (0..64), or direction (must be rx/tx/tx_rx).
  • A CAN signal has out-of-range start_bit (0..63), bit_length (1..64), unknown byte_order, or scale == 0.
  • A tx_rx CAN frame is missing response_id.

Failures are logged at error level with the offending command/sequence name; the rest of the profile is still loaded if subsequent items validate.

  • Start by capturing a real *IDN? response — your patterns regex should match it case-insensitively without being so loose it catches sibling models you don’t support.
  • Profiles are matched in load order; for vendors with both old and new product lines, write the more specific pattern first.
  • Use force_query: true for property-style commands where the SCPI getter looks like MEAS:VOLT? rather than VOLT?.
  • For oscilloscope traces, set returns.type: vector and provide x_start_query / x_increment_query so client code gets correct time-domain axes.
  • Mark anything that can damage hardware (OUTP ON on an SMU at full scale, magnet ramps) with is_dangerous: true and route ramps through requires_sweep: true so they go through the safety-checked sweep path.
  • Drop your YAML in PROFILE_DIR, then galois-edge configure set PROFILES_ENABLED true and restart — the daemon will log the loaded profiles and any validation errors.