From 43a24ee9c47bcf4cad5d56cddee09b85242d144c Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 28 Jan 2026 17:59:42 +0100 Subject: [PATCH 1/3] add current state of schemata from secop-check repo --- schema/acquisition.yaml | 116 ++++++++++++++++++ schema/commands.yaml | 64 ++++++++++ schema/communicator.yaml | 12 ++ schema/datatypes.yaml | 193 ++++++++++++++++++++++++++++++ schema/drivable.yaml | 12 ++ schema/features.yaml | 15 +++ schema/parameters.yaml | 113 ++++++++++++++++++ schema/postfixes.yaml | 35 ++++++ schema/power_supply.yaml | 68 +++++++++++ schema/properties.yaml | 245 +++++++++++++++++++++++++++++++++++++++ schema/readable.yaml | 18 +++ schema/version-1.0.yaml | 83 +++++++++++++ schema/version-1.1.yaml | 91 +++++++++++++++ schema/version-2.0.yaml | 113 ++++++++++++++++++ schema/writable.yaml | 17 +++ 15 files changed, 1195 insertions(+) create mode 100644 schema/acquisition.yaml create mode 100644 schema/commands.yaml create mode 100644 schema/communicator.yaml create mode 100644 schema/datatypes.yaml create mode 100644 schema/drivable.yaml create mode 100644 schema/features.yaml create mode 100644 schema/parameters.yaml create mode 100644 schema/postfixes.yaml create mode 100644 schema/power_supply.yaml create mode 100644 schema/properties.yaml create mode 100644 schema/readable.yaml create mode 100644 schema/version-1.0.yaml create mode 100644 schema/version-1.1.yaml create mode 100644 schema/version-2.0.yaml create mode 100644 schema/writable.yaml diff --git a/schema/acquisition.yaml b/schema/acquisition.yaml new file mode 100644 index 00000000..4157eace --- /dev/null +++ b/schema/acquisition.yaml @@ -0,0 +1,116 @@ +--- +kind: Property +name: acquisition_channels +version: 2 +dataty: struct +description: | + Specifies the channels belonging to an AcquisitionController. + +--- +kind: Command +name: prepare +version: 2 +optional: true +argument: none +result: none +description: | + Prepare data acquisition so that "go" is immediate. + +--- +kind: Parameter +name: goal +version: 2 +optional: true +readonly: false +datainfo: parent +description: | + Goal value to reach for stopping data acquisition. + +--- +kind: Parameter +name: roi +version: 2 +optional: true +readonly: false +datainfo: + type: array + members: + type: tuple + members: + - int + - int +description: | + Enables checking the "goal" parameter. + +--- +kind: Command +name: get_data +version: 2 +optional: true +argument: none +result: matrix +description: | + Get the full data from a matrix type channel. + +--- +kind: Interface +name: AcquisitionController +version: 2 +description: | + A base SECoP interface class for modules that control a data acquisition + process. +parameters: + - status:1 +commands: + - prepare:2 + - go: + definition: go:1 + optional: false + description: Start the data acquisition. + - hold: + definition: hold:1 + description: Pause the data acquisition. + - stop: + definition: stop:1 + description: Stop the data acquisition. +properties: + - acquisition_channels:2 + +--- +kind: Interface +name: AcquisitionChannel +version: 2 +base: Readable:1 +description: | + A base SECoP interface class for a single channel of a multi-channel data + acquisition process. +parameters: + - goal:2 + - roi:2 +commands: + - get_data:2 + +--- +kind: Interface +name: Acquisition +version: 2 +base: Readable:1 +description: | + A combined AcquisitionController and AcquisitionChannel for a single-channel + data acquisition process. +parameters: + - goal:2 + - roi:2 +commands: + - prepare:2 + - go: + definition: go:1 + optional: false + description: Start the data acquisition. + - hold: + definition: hold:1 + description: Pause the data acquisition. + - stop: + definition: stop:1 + description: Stop the data acquisition. + - get_data:2 diff --git a/schema/commands.yaml b/schema/commands.yaml new file mode 100644 index 00000000..1ae50343 --- /dev/null +++ b/schema/commands.yaml @@ -0,0 +1,64 @@ +--- +kind: Command +name: go +version: 1 +argument: none +result: none +description: | + start an action. If this is present, changing the target parameter should not initiate any action. + +--- +kind: Command +name: shutdown +version: 1 +argument: none +result: none +description: | + Shut down the hardware (not the SECNode). When this command is sent, and the + status is DISABLED, it is safe to switch off the related device. + +--- +kind: Command +name: reset +version: 1 +argument: none +result: none +description: | + Put the module in a state predefined by the implementation. + +--- +kind: Command +name: clear_errors +version: 1 +argument: none +result: none +description: | + Tries to clear up the error state. May be called when status is ERROR. + +--- +kind: Command +name: control_off +version: 1 +argument: none +result: none +description: | + Turn off active control on this module. + +--- +kind: Command +name: stop +version: 1 +argument: none +result: none +description: | + Stop the current value-changing operation. If not driving, no effect. + +--- +kind: Command +name: hold +version: 1 +optional: true +argument: none +result: none +description: | + Cease movement, be ready to continue soon, target value is kept. diff --git a/schema/communicator.yaml b/schema/communicator.yaml new file mode 100644 index 00000000..b6267db3 --- /dev/null +++ b/schema/communicator.yaml @@ -0,0 +1,12 @@ +kind: Interface +name: Communicator +version: 1 +description: | + A base SECoP interface class for modules who communicate directly with + the hardware. +commands: + - communicate: + argument: string + result: string + description: | + Communicate with the hardware directly. diff --git a/schema/datatypes.yaml b/schema/datatypes.yaml new file mode 100644 index 00000000..fece22bf --- /dev/null +++ b/schema/datatypes.yaml @@ -0,0 +1,193 @@ +--- +kind: Datainfo +name: double +version: 1 +description: A floating point value. +dataty: number +dataprops: + min: + dataty: number + optional: true + max: + dataty: number + optional: true + unit: + dataty: string + optional: true + absolute_resolution: + dataty: number + optional: true + relative_resolution: + default: 1.2e-7 + dataty: number + optional: true + fmtstr: + dataty: string + default: "%.6g" + optional: true + +--- +kind: Datainfo +name: scaled +version: 1 +description: A floating point transported as integer with defined scale. +dataty: int +dataprops: + min: + dataty: int + max: + dataty: int + scale: + dataty: number + unit: + dataty: string + optional: true + absolute_resolution: + dataty: number + optional: true + relative_resolution: + default: 1.2e-7 + dataty: number + optional: true + fmtstr: + dataty: string + default: "%.6g" + optional: true + +--- +kind: Datainfo +name: int +version: 1 +description: An integral value. +dataty: int +dataprops: + min: + dataty: int + max: + dataty: int + unit: + dataty: string + optional: true + +--- +kind: Datainfo +name: bool +version: 1 +description: A boolean value. +dataty: bool +dataprops: {} + +--- +kind: Datainfo +name: enum +version: 1 +description: Collection of predefined values mapped to integers. +dataty: int +dataprops: + members: + dataty: + type: struct + members: int + +--- +kind: Datainfo +name: string +version: 1 +description: A string. +dataty: string +dataprops: + minchars: + optional: true + dataty: int + maxchars: + optional: true + dataty: int + isUTF8: + optional: true + dataty: bool + +--- +kind: Datainfo +name: blob +version: 1 +description: Base64 encoded string for binary types. +dataty: string +dataprops: + maxbytes: + dataty: int + minbytes: + dataty: int + default: 0 + optional: true + +--- +kind: Datainfo +name: array +version: 1 +description: Multiple values of the same type. +dataty: array +dataprops: + members: + dataty: datainfo + maxlen: + dataty: int + minlen: + default: 0 + dataty: int + optional: true + +--- +kind: Datainfo +name: tuple +version: 1 +description: Finite sequence of variously typed items. +dataty: array +dataprops: + members: + dataty: + type: array + members: datainfo + +--- +kind: Datainfo +name: struct +version: 1 +description: Mixed type collection of named values. +dataty: struct +dataprops: + members: + dataty: + type: struct + members: datainfo + optional: + dataty: + type: array + members: string + optional: true + +--- +kind: Datainfo +name: matrix +version: 2 +description: Binary n-dimensional arrays. +dataty: + type: struct + members: + len: + type: array + members: int + blob: string +dataprops: + names: + dataty: + type: array + members: string + maxlen: + dataty: + type: array + members: int + elementtype: + dataty: string + compression: + dataty: string + optional: true diff --git a/schema/drivable.yaml b/schema/drivable.yaml new file mode 100644 index 00000000..894dc38e --- /dev/null +++ b/schema/drivable.yaml @@ -0,0 +1,12 @@ +--- +kind: Interface +name: Drivable +version: 1 +# All accessibles from the base are "inherited". +base: Writable:1 +description: | + A base SECoP interface class for modules whose values changes "slowly", + so that the change can be stopped. +commands: + - stop:1 + - hold:1 diff --git a/schema/features.yaml b/schema/features.yaml new file mode 100644 index 00000000..40e2d55f --- /dev/null +++ b/schema/features.yaml @@ -0,0 +1,15 @@ +--- +kind: Feature +name: HasOffset +version: 1 +description: | + This feature is indicating that the value and target parameters are raw values, which + need to be corrected by an offset. A module with the feature `HasOffset` must have + a parameter `offset`, which indicates to all clients that values are to be converted + by the following formulas: + + ECS value = SECoP value + offset + + SECoP target = ECS target - offset +parameters: + - offset:1 diff --git a/schema/parameters.yaml b/schema/parameters.yaml new file mode 100644 index 00000000..4a863eed --- /dev/null +++ b/schema/parameters.yaml @@ -0,0 +1,113 @@ +--- +kind: Parameter +name: value +version: 1 +datainfo: any +readonly: true +description: | + The value parameter. + +--- +kind: Parameter +name: status +version: 1 +datainfo: + type: tuple + members: [enum, string] +readonly: true +description: | + The status parameter. + +--- +kind: Parameter +name: target +version: 1 +datainfo: any +readonly: false +description: | + The target value for the module. By setting this parameter, a move + operation is started. + +--- +kind: Parameter +name: pollinterval +version: 1 +datainfo: double +readonly: false +description: | + Hint for polling interval in seconds. + +--- +kind: Parameter +name: offset +version: 1 +datainfo: number +readonly: false +description: | + Offset parameter for the HasOffset feature. + +--- +kind: Parameter +name: mode +version: 1 +datainfo: enum +readonly: false +description: | + Operation mode of the module. + +--- +kind: Parameter +name: target_limits +version: 1 +datainfo: + type: tuple + members: [number, number] +readonly: true +description: | + Changeble user-defined limits for the target parameter of a module. + Has to respect the limits of the target parameter itself. + +--- +kind: Parameter +name: ramp +version: 1 +datainfo: number +readonly: false +description: | + Desired ramp. Unit is main-unit/min. + +--- +kind: Parameter +name: setpoint +version: 1 +datainfo: number +readonly: true +description: | + ramping setpoint + +--- +kind: Parameter +name: time_to_target +version: 1 +datainfo: number +readonly: true +description: | + Expected time to reach the target in seconds + +--- +kind: Parameter +name: controlled_by +version: 1 +datainfo: string +readonly: false +description: | + indicates the module this modules value is controlled by. + +--- +kind: Parameter +name: control_active +version: 1 +datainfo: bool +readonly: true +description: | + Indicates whether this module is actively controlling. diff --git a/schema/postfixes.yaml b/schema/postfixes.yaml new file mode 100644 index 00000000..d9c7ea55 --- /dev/null +++ b/schema/postfixes.yaml @@ -0,0 +1,35 @@ +--- +kind: ParameterPostfix +name: _limits +version: 2 +description: | + Specifies changeable limits of the parameter. +datainfo: + type: tuple + members: + - parent + - parent + +--- +kind: ParameterPostfix +name: _min +version: 2 +description: | + Specifies the changeable minimum of the parameter. +datainfo: parent + +--- +kind: ParameterPostfix +name: _max +version: 2 +description: | + Specifies the changeable maximum of the parameter. +datainfo: parent + +--- +kind: ParameterPostfix +name: _enable +version: 2 +description: | + Specifies if the parameter's effect is enabled. +datainfo: bool diff --git a/schema/power_supply.yaml b/schema/power_supply.yaml new file mode 100644 index 00000000..eb237f32 --- /dev/null +++ b/schema/power_supply.yaml @@ -0,0 +1,68 @@ +--- +kind: Property +name: quantity +version: 1 +dataty: string +optional: true +description: | + A hint of the physical quantity represented by this parameter. + +--- +kind: System +name: PowerSupply +version: 1 +description: | + A power supply consisting of current and voltage regulation modules. + The active module can be switched with the parameter `control_active`. +modules: + current: + definition: Drivable:1 + description: Controls the current. + properties: + # This property has a general definition, but here the description + # defines a required value. + - quantity: + definition: quantity:1 + description: Must be set to "current". + value: "current" + parameters: + # This parameter is already defined by Drivable, but the required + # datainfo is made more concrete by this definition. + - value: + datainfo: + type: double + unit: A + # This parameter is completely specific to this module. + - voltage_limit: + description: | + Compliance voltage applied when supply is in current mode. + datainfo: + type: double + unit: V + optional: true + - power_limit: + description: | + Power limit applied when supply is in current mode. + datainfo: + type: double + unit: W + optional: true + - control_active: + definition: control_active:1 + description: | + If true, power supply is in current mode. + Setting `voltage:control_active` resets this to false. + # similar for power, voltage + resistance: + definition: Readable:1 + description: Readback for the measured resistance. + optional: true + parameters: + - value: + datainfo: + type: number + unit: Ohm + properties: + - quantity: + definition: quantity:1 + value: "resistance" diff --git a/schema/properties.yaml b/schema/properties.yaml new file mode 100644 index 00000000..40038550 --- /dev/null +++ b/schema/properties.yaml @@ -0,0 +1,245 @@ +--- +kind: Property +name: description +version: 1 +dataty: string +description: | + Human readable description. + +--- +kind: Property +name: equipment_id +version: 1 +dataty: string +description: | + Worldwide unique identification string. + +--- +kind: Property +name: firmware +version: 1 +dataty: string +optional: true +description: | + short string naming the version of the SEC node software. + +--- +kind: Property +name: implementor +version: 1 +dataty: string +optional: true +description: | + Globally unique name of the implementor of this SECNode. + +--- +kind: Property +name: timeout +version: 1 +dataty: number +optional: true +description: | + Timeout in seconds for the SECNode to send an answer. + +--- +kind: Property +name: interface_classes +version: 1 +dataty: + type: array + members: string +description: | + List of the defined interface classes which are implemented for the Module. + +--- +kind: Property +name: features +version: 1 +dataty: + type: array + members: string +description: | + List of supported features. + +--- +kind: Property +name: visibility +version: 1 +dataty: + type: oneof + values: + - user + - advanced + - expert +optional: true +description: | + Hint for clients to use for access control and filtering. + +--- +kind: Property +name: visibility +version: 2 +dataty: + type: oneof + values: + - "www" + - "wwr" + - "ww-" + - "wrr" + - "wr-" + - "w--" + - "rrr" + - "rr-" + - "r--" + - "---" +optional: true +description: | + Hint for clients to use for access control and filtering. + +--- +kind: Property +name: group +version: 1 +dataty: string +optional: true +description: | + Grouping hint for multiple modules. + +--- +kind: Property +name: meaning +version: 1 +dataty: + type: tuple + members: + - type: oneof + values: + - temperature + - temperature_regulation + - magneticfield + - magneticfield_regulation + - electricfield + - electricfield_regulation + - pressure + - pressure_regulation + - rotation_z + - rotation_z_regulation + - humidity + - humidity_regulation + - viscosity + - viscosity_regulation + - flowrate + - flowrate_regulation + - concentration + - concentration_regulation + - type: int + min: 0 + max: 50 +optional: true +description: | + Tuple describing one of the predefined meanings and a importance value. + +--- +kind: Property +name: meaning +version: 2 +dataty: + type: struct + members: + function: + type: oneof + values: + - temperature + - temperature_regulation + - magneticfield + - magneticfield_regulation + - electricfield + - electricfield_regulation + - pressure + - pressure_regulation + - rotation_z + - rotation_z_regulation + - humidity + - humidity_regulation + - viscosity + - viscosity_regulation + - flowrate + - flowrate_regulation + - concentration + - concentration_regulation + - ph + - ph_regulation + - conductivity + - conductivity_regulation + - voltage + - voltage_regulation + - surfacepressure + - surfacepressure_regulation + - stress + - stress_regulation + - strain + - strain_regulation + - shear + - shear_regulation + - level + - level_regulation + importance: + type: int + min: 0 + max: 50 + belongs_to: string + link: string + key: string + optional: + - function + - importance + - belongs_to + - link + - key +optional: true +description: | + Metadata describing the meaning of the element in a structured way, optionally + linking to a knowledge repository. + +--- +kind: Property +name: implementation +version: 1 +dataty: string +description: | + A string indicating information about the implementation of the module, + like a python class name. + +--- +kind: Property +name: readonly +version: 1 +dataty: bool +description: | + Indicates whether the parameter can be written by the ECS. + +--- +kind: Property +name: datainfo +version: 1 +dataty: datainfo +description: | + Describes the type of the accessible's (or command argument/result's) value. + +--- +kind: Property +name: constant +version: 1 +dataty: parent # same as the parameter with the property +optional: true +description: | + Indicates a constant value that will not be included in updates, and does + not change. + +--- +kind: Property +name: system +version: 2 +dataty: string +description: | + Gives the defined system schema which this System belongs to. diff --git a/schema/readable.yaml b/schema/readable.yaml new file mode 100644 index 00000000..22a742ca --- /dev/null +++ b/schema/readable.yaml @@ -0,0 +1,18 @@ +--- +kind: Interface +name: Readable +version: 1 +description: | + Base class for things that can be read, like Sensors. +parameters: + - value: + # Refer to the element above to get the definition of this parameter. + definition: value:1 + # A more specific description can be given in addition to the one already + # provided in the "target" element above. + description: | + The main value of the module. + - status: + definition: status:1 + description: | + Current status of the module. diff --git a/schema/version-1.0.yaml b/schema/version-1.0.yaml new file mode 100644 index 00000000..e8ffda5b --- /dev/null +++ b/schema/version-1.0.yaml @@ -0,0 +1,83 @@ +--- +kind: Repository +name: "SECoP 1.0" +version: 1 +link: https://github.com/SampleEnvironment/SECoP/blob/master/protocol/SECoP_Specification_V1.0.rst +description: | + SECoP version 1.0 + +files: + - commands.yaml + - communicator.yaml + - datatypes.yaml + - drivable.yaml + - parameters.yaml + - properties.yaml + - readable.yaml + - writable.yaml + +systems: [] +interfaces: + - Readable:1 + - Writable:1 + - Drivable:1 + - Communicator:1 +features: [] +parameters: + - pollinterval:1 + - value:1 + - status:1 + - target:1 + - mode:1 + - offset:1 + - ramp:1 + - setpoint:1 + - time_to_target:1 +postfixes: [] +commands: + - go:1 + - stop:1 + - hold:1 + - shutdown:1 + - reset:1 + - clear_errors:1 + +properties: + SECNode: + - description:1 + - equipment_id:1 + - firmware:1 + - implementor:1 + - timeout:1 + System: [] + Module: + - description:1 + - implementor:1 + - interface_classes:1 + - visibility:1 + - group:1 + - meaning:1 + Parameter: + - datainfo:1 + - description:1 + - visibility:1 + - group:1 + - constant:1 + - readonly:1 + Command: + - datainfo:1 + - description:1 + - visibility:1 + - group:1 + +datainfo: + - double:1 + - int:1 + - scaled:1 + - bool:1 + - enum:1 + - string:1 + - blob:1 + - array:1 + - tuple:1 + - struct:1 diff --git a/schema/version-1.1.yaml b/schema/version-1.1.yaml new file mode 100644 index 00000000..3e094252 --- /dev/null +++ b/schema/version-1.1.yaml @@ -0,0 +1,91 @@ +--- +kind: Repository +name: "SECoP 1.1" +version: 1 +link: https://github.com/SampleEnvironment/SECoP/blob/master/protocol/SECoP_Specification_V1.1.rst +description: | + SECoP version 1.1 + +files: + - commands.yaml + - communicator.yaml + - datatypes.yaml + - drivable.yaml + - features.yaml + - parameters.yaml + - properties.yaml + - readable.yaml + - writable.yaml + +systems: [] +interfaces: + - Readable:1 + - Writable:1 + - Drivable:1 + - Communicator:1 +features: + - HasOffset:1 +parameters: + - pollinterval:1 + - value:1 + - status:1 + - target:1 + - mode:1 + - offset:1 + - target_limits:1 + - ramp:1 + - setpoint:1 + - time_to_target:1 + - controlled_by:1 + - control_active:1 +postfixes: [] +commands: + - go:1 + - stop:1 + - hold:1 + - shutdown:1 + - reset:1 + - clear_errors:1 + - control_off:1 + +properties: + SECNode: + - description:1 + - equipment_id:1 + - firmware:1 + - implementor:1 + - timeout:1 + System: [] + Module: + - description:1 + - implementor:1 + - implementation:1 + - interface_classes:1 + - features:1 + - visibility:1 + - group:1 + - meaning:1 + Parameter: + - datainfo:1 + - description:1 + - visibility:1 + - group:1 + - constant:1 + - readonly:1 + Command: + - datainfo:1 + - description:1 + - visibility:1 + - group:1 + +datainfo: + - double:1 + - int:1 + - scaled:1 + - bool:1 + - enum:1 + - string:1 + - blob:1 + - array:1 + - tuple:1 + - struct:1 diff --git a/schema/version-2.0.yaml b/schema/version-2.0.yaml new file mode 100644 index 00000000..6f332fae --- /dev/null +++ b/schema/version-2.0.yaml @@ -0,0 +1,113 @@ +--- +kind: Repository +name: "SECoP 2.0" +version: 1 +# TODO: update to persistent link +link: https://github.com/SampleEnvironment/SECoP/blob/master/protocol/specification +description: | + SECoP version 2.0 + +files: + - acquisition.yaml + - commands.yaml + - communicator.yaml + - datatypes.yaml + - drivable.yaml + - features.yaml + - parameters.yaml + - postfixes.yaml + - properties.yaml + - readable.yaml + - writable.yaml + +systems: [] +interfaces: + - Readable:1 + - Writable:1 + - Drivable:1 + - Communicator:1 + - AcquisitionController:2 + - AcquisitionChannel:2 + - Acquisition:2 +features: + - HasOffset:1 +parameters: + - pollinterval:1 + - value:1 + - status:1 + - target:1 + - mode:1 + - offset:1 + - ramp:1 + - setpoint:1 + - time_to_target:1 + - controlled_by:1 + - control_active:1 +postfixes: + - _limits:2 + - _min:2 + - _max:2 + - _enable:2 +commands: + - go:1 + - stop:1 + - hold:1 + - shutdown:1 + - reset:1 + - clear_errors:1 + - control_off:1 + +properties: + SECNode: + # implicit: modules, systems + - description:1 + - equipment_id:1 + - firmware:1 + - implementor:1 + - timeout:1 + # todo: schemata + System: + # implicit: modules + - description:1 + - system:2 + Module: + # implicit: accessibles + - description:1 + - implementor:1 + - implementation:1 + - interface_classes:1 + - features:1 + - visibility:1 + - visibility:2 + - group:1 + - meaning:1 + - meaning:2 + Parameter: + - datainfo:1 + - description:1 + - visibility:1 + - visibility:2 + - group:1 + - constant:1 + - readonly:1 + - meaning:2 + Command: + - datainfo:1 + - description:1 + - visibility:1 + - visibility:2 + - group:1 + - meaning:2 + +datainfo: + - double:1 + - int:1 + - scaled:1 + - bool:1 + - enum:1 + - string:1 + - blob:1 + - array:1 + - tuple:1 + - struct:1 + - matrix:2 diff --git a/schema/writable.yaml b/schema/writable.yaml new file mode 100644 index 00000000..411e936b --- /dev/null +++ b/schema/writable.yaml @@ -0,0 +1,17 @@ +--- +kind: Interface +name: Writable +version: 1 +# All accessibles from the base are "inherited". +base: Readable:1 +description: | + A base SECoP interface class for modules that can have their value changed. + The change has to happen nearly immediately. +parameters: + - target: + # Refer to the element above to get the definition of this parameter. + definition: target:1 + # A more specific description can be given in addition to the one already + # provided in the "target" element above. + description: | + The target value the modules main value should be set to. From 80c930293e34be0716bf7a161294477962513ea9 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 28 Jan 2026 18:13:34 +0100 Subject: [PATCH 2/3] add RFC-102/103 to specification --- protocol/specification/accessibles.rst | 2 + protocol/specification/additional.rst | 1 + protocol/specification/changes.rst | 5 +- protocol/specification/descriptive.rst | 5 + protocol/specification/schemata.rst | 409 +++++++++++++++++++++++++ rfcs/RFC-102-schemata.rst | 2 +- 6 files changed, 421 insertions(+), 3 deletions(-) create mode 100644 protocol/specification/schemata.rst diff --git a/protocol/specification/accessibles.rst b/protocol/specification/accessibles.rst index d3ee4ddf..ea29a819 100644 --- a/protocol/specification/accessibles.rst +++ b/protocol/specification/accessibles.rst @@ -1,3 +1,5 @@ +.. _accessibles: + Parameters and commands ======================= diff --git a/protocol/specification/additional.rst b/protocol/specification/additional.rst index ca131fd9..085cbc8e 100644 --- a/protocol/specification/additional.rst +++ b/protocol/specification/additional.rst @@ -3,5 +3,6 @@ Additional topics .. toctree:: + schemata security future diff --git a/protocol/specification/changes.rst b/protocol/specification/changes.rst index 31ab00ea..414185a9 100644 --- a/protocol/specification/changes.rst +++ b/protocol/specification/changes.rst @@ -40,11 +40,12 @@ loss of functionality. .. rubric:: Backwards compatible changes -.. TODO machine readable, systems - - The specification text has been generally restructured and edited to improve clarity and presentation. +- Machine readable definition of specification entities has been specified + (:ref:`rfc-102` and :ref:`rfc-103`). + - The optional `check`/`checked` messages have been added, as well as the `checkable` accessible property (:issue:`075 New messages check and checked`). diff --git a/protocol/specification/descriptive.rst b/protocol/specification/descriptive.rst index 39d7c1b4..77a10860 100644 --- a/protocol/specification/descriptive.rst +++ b/protocol/specification/descriptive.rst @@ -121,6 +121,11 @@ Optional SEC node properties well below this value, i.e. this is a reply-timeout. Default: 10 sec, *see* :issue:`004 The Timeout SEC Node Property`. +.. node-property:: schemata + + A list of URLs of :ref:`YAML repositories ` describing the + structure and semantics of the node, see :ref:`schema-links`. + .. _module-description: diff --git a/protocol/specification/schemata.rst b/protocol/specification/schemata.rst new file mode 100644 index 00000000..f87e8c48 --- /dev/null +++ b/protocol/specification/schemata.rst @@ -0,0 +1,409 @@ +.. _schemata: + +Schema definitions for SECoP interfaces and semantics +===================================================== + +See also :ref:`rfc-102` and :ref:`rfc-103`. + +The SECoP data model described in this specification is comprised of many +different kinds of entities, such as modules, parameters and properties. + +Each of the pre-defined entitites specifies certain semantics -- for example, +what does the interface class `Readable` mean and which are its required and +optional parameters and commands. + +The goal of this part of the specification is to formalize these definitions in +a more machine-processable form, while not losing human readability and too much +flexibility. This in turn enables automatic validation and checking of a SECoP +node's interface against the specification. + +The entities described are: + +- :ref:`systems` +- :ref:`interface-classes` and :ref:`features` +- :ref:`Parameters, parameter postfixes, commands ` +- :ref:`Properties ` +- :ref:`data-types` + +The definitions for standard entities should be accessible in a central +repository. SEC nodes should link to their respective specifications in order +to enable three things: + +- The implementors of clients can get a description of the functionality of + these interface classes. +- A client can use the extended description to provide further functionality. +- The structure of the SECNode can be verified to follow the interface. + + +YAML definitions +---------------- + +Definitions are given in the YAML format, in a form similar to `object +descriptions in Kubernetes +`_. +Multiple definitions can be placed in the same file, using the "document +separator"s of YAML. + +Each entity has a few common fields: + +``kind`` + The kind of entity, one of ``Repository``, ``System``, ``Interface``, + ``Feature``, ``Parameter``, ``ParameterPostfix``, ``Command``, ``Property``, + ``Datainfo``. +``name`` + The entity's unique name. +``version`` + The revision of this definition, as a simple integer. +``link`` + A URL linking to the description of the entity. Optional. +``description`` + A human-readable description. + +Then, depending on the ``kind``, different keys can be present: + +**For repositories:** + +A repository defines a collection of entities, such as "SECoP 1.0" or "Rock-IT +SECoP extensions". + +``files`` + A list of other YAML file paths, relative to this file, in which the entities + making up the repository can be found. +``systems``, ``interfaces``, ``features``, ``parameters``, ``postfixes``, ``commands``, ``datainfo`` + Lists of references_ to entities that are part of the repository. +``properties`` + Dictionary of lists of references_ to properties in the repository, keyed + by the entity they can appear on: ``SECNode``, ``System``, ``Module``, + ``Parameter``, ``Command`` + +**For interface classes and features:** + +``base`` + Reference to the base interface/feature this one is derived from. +``properties`` + References_ to the properties that are required/allowed on this entity + (depending on their "optional" setting). +``parameters``, ``commands`` + References_ to the accessibles that are required/allowed on this entity. + +**For parameters:** + +``readonly`` + Boolean, if the parameter should be readonly. +``datainfo`` + Specification of the parameter's datainfo_. +``properties`` + References_ to the properties that are possible on this entity. +``optional`` + Boolean, if the parameter is by default optional when added in + interfaces/features. + +**For parameter postfixes:** + +``readonly`` + Boolean, if the parameter should be readonly. +``datainfo`` + Specification of the parameter's datainfo_. +``properties`` + References_ to the properties that are possible on this entity. + +**For commands:** + +``argument`` + The list of argument datainfo_\s, or "none". +``result`` + The return value datainfo_, or "none". +``properties`` + References_ to the properties that are possible on this entity. +``optional`` + Boolean, if the command is by default optional when added in + interfaces/features. + +**For properties:** + +``dataty`` + Specification of the property's `JSON type`_. +``optional`` + Boolean, if the property is by default optional. +``value`` + If present, forces the property's value to be this - this is mainly + useful for Systems. + +**For datainfos:** + +``dataty`` + Specification of the datainfo's `JSON type`_ (i.e. transport layer). +``dataprops`` + A dictionary of data properties of the datainfo specification. Each one + can have the following properties: + + ``dataty`` + Specification of the datainfo property's `JSON type`_. + ``optional`` + Boolean, if the property is optional. + ``default`` + A default value. + +**For systems:** + +``base`` + Reference to the base system this one is derived from. +``modules`` + A dictionary of module names and their definitions. Each item is + either a reference to an existing interface/feature definition or a + full inline interface definition. +``systems`` + A dictionary of subsystem names and their definitions, analogous to + ``modules``. + +Entity versions +^^^^^^^^^^^^^^^ + +When a new entity is proposed, the ``version`` starts at 0. A version of 0 +does not give a stability guarantee, unlike versions larger than 0. If an +entity is accepted and introduced into the specification, the version is +defined as the major number of the specification it first appears in. +Changes to the interface afterwards require a major specification version +bump and also bump the entity's version number. + +Example +^^^^^^^ + +As an example, a YAML description for some standard entities would look like +this: + +.. code:: yaml + + --- + kind: Parameter + name: target + version: 1 + datainfo: any + readonly: false + description: | + The target value for the module. By setting this parameter, a move + operation is started. + + --- + kind: Command + name: stop + version: 1 + argument: none + result: none + description: | + Stop the current value-changing operation. If not driving, no effect. + + --- + kind: Interface + name: Writable + version: 1 + # All accessibles from the base are "inherited". + base: Readable:1 + description: | + A base SECoP interface class for modules that can have their value changed, + reporting their status in the meantime. + parameters: + - target: + # Refer to this entity to get the definition of this parameter. + definition: target:1 + # A more specific description can be given in addition to the one already + # provided in the "definition" entity above. + description: ... + + --- + kind: Interface + name: Drivable + version: 1 + base: Writable:1 + description: | + A base SECoP interface class for modules whose values changes "slowly", + so that the change can be stopped. + commands: + - stop:1 + + --- + kind: Feature + name: HasOffset + version: 1 + description: | + This feature is indicating that the value and target parameters are raw values, which + need to be corrected by an offset. A module with the feature `HasOffset` must have + a parameter `offset`, which indicates to all clients that values are to be converted + by the following formulas: + + ECS value = SECoP value + offset + + SECoP target = ECS target - offset + parameters: + - offset:1 + +Example for a complete system that describes a simple power supply inspired by +:issue:`078 Interacting Modules - use case power supply`: + +.. code:: yaml + + --- + kind: Property + name: quantity + version: 1 + datainfo: string + optional: true + description: | + A hint of the physical quantity represented by this parameter. + + --- + kind: System + name: PowerSupply + version: 1 + description: | + A power supply consisting of current and voltage regulation modules. + The active module can be switched with the parameter `control_active`. + modules: + current: + definition: Drivable:1 + description: Controls the current. + properties: + # This property has a general definition, but here the description + # defines a required value. + - quantity: + definition: quantity:1 + description: Must be set to "current". + parameters: + # This parameter is already defined by Drivable, but the required + # datainfo is made more concrete by this definition. + - value: + datainfo: + type: double + unit: A + # This parameter is completely specific to this module. + - voltage_limit: + description: | + Compliance voltage applied when supply is in current mode. + datainfo: + type: double + unit: V + optional: true + - power_limit: + description: | + Power limit applied when supply is in current mode. + datainfo: + type: double + unit: W + optional: true + - control_active: + definition: control_active:1 + description: | + If true, power supply is in current mode. + Setting `voltage:control_active` resets this to false. + # similar for power, voltage + resistance: + definition: Readable:1 + description: Readback for the measured resistance. + optional: true + parameters: + - value: + datainfo: + type: number + unit: Ohm + properties: + - quantity: + definition: quantity:1 + description: Must be set to "resistance". + + +References +^^^^^^^^^^ + +A reference to another entity is one of two things: + +- A string, which specifies the entity name and version separated by a colon, + such as ``"Readable:1"``. + +- A dictionary that inlines the entity, with a ``definition`` key that + references an existing entity as ``name:version`` and adds/overrides other + keys, most commonly the ``description`` to make it more specific. + + See the example above for how to use this. + + +Datainfo +^^^^^^^^ + +``datainfo`` entries are either strings (the name of the datainfo entity) or +dictionaries with a key ``type`` (the name of the datainfo entity) and all +dataprops of the respective datainfo. + +``"any"`` is allowed for unspecified datainfos. + + +JSON type +^^^^^^^^^ + +In ``dataty`` entries, you can specify the JSON type: + +- Unspecified: ``dataty: any`` +- Boolean: ``dataty: bool`` +- String: ``dataty: string`` +- Number: ``dataty: number`` +- Integer: ``dataty: int`` + +- Array (JSON array):: + + dataty: + type: array + members: # the dataty of array members + +- Tuple (JSON array):: + + dataty: + type: tuple + members: [, ...] # list of datatys + +- Struct (JSON object):: + + dataty: + type: struct + members: + membername: + ... + optional: [...] # list of optional member names + +Special cases: + +- Any datainfo: ``dataty: datainfo`` +- Same type as the parent accessible: ``dataty: parent`` + + +.. _schema-links: + +Linking to schemata +------------------- + +A schema URL is of the format: ``https://.../file.yaml``, referencing a YAML +file written according to this chapter. + +In the SEC node descriptive data, the optional property `schemata` is a list of +schema URLs. All given URLs should be parsed by interested consumers (such as +clients or validators). The entities specified in all ``Repository``\s they +contain are merged into the set of entities against which an automatic +validation is run. + +This means that once `schemata` is present, all needed Repositorys needed to +validate all systems, modules, parameters etc. should be linked there. + + +Available repositories +---------------------- + +The core SECoP repositories for the different specification versions +are maintained in the SECoP repository at + +https://github.com/SampleEnvironment/SECoP/tree/master/schema + +To specify a certain SECoP version for a node, at least one of these URLs must +be present: + +- https://raw.githubusercontent.com/SampleEnvironment/SECoP/refs/heads/master/schema/version-1.0.yaml +- https://raw.githubusercontent.com/SampleEnvironment/SECoP/refs/heads/master/schema/version-1.1.yaml +- https://raw.githubusercontent.com/SampleEnvironment/SECoP/refs/heads/master/schema/version-2.0.yaml +- or upcoming later versions diff --git a/rfcs/RFC-102-schemata.rst b/rfcs/RFC-102-schemata.rst index 6d6b0da3..5ee373fc 100644 --- a/rfcs/RFC-102-schemata.rst +++ b/rfcs/RFC-102-schemata.rst @@ -33,7 +33,7 @@ These entities are: - Interface classes and features - Parameters, parameter postfixes, commands and properties - Data types -- Systems (see RFC-004) +- Systems (see RFC-104) The definitions for standard entities should be accessible in a central repository. SECNodes should link to their respective specifications in order to From 62ad25bb71a5795c18709f3a49bdc8fa2c39f954 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 28 Jan 2026 19:14:54 +0100 Subject: [PATCH 3/3] add RFC-104 to specification --- protocol/specification/descriptive.rst | 5 ++ protocol/specification/semantics.rst | 1 + protocol/specification/structure.rst | 11 +++ protocol/specification/systems.rst | 114 +++++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 protocol/specification/systems.rst diff --git a/protocol/specification/descriptive.rst b/protocol/specification/descriptive.rst index 77a10860..7242cc42 100644 --- a/protocol/specification/descriptive.rst +++ b/protocol/specification/descriptive.rst @@ -121,6 +121,11 @@ Optional SEC node properties well below this value, i.e. this is a reply-timeout. Default: 10 sec, *see* :issue:`004 The Timeout SEC Node Property`. +.. node-property:: systems + + A JSON object of system mappings for systems contained in this SEC node, see + :ref:`systems`. + .. node-property:: schemata A list of URLs of :ref:`YAML repositories ` describing the diff --git a/protocol/specification/semantics.rst b/protocol/specification/semantics.rst index 79ceed28..be8b516b 100644 --- a/protocol/specification/semantics.rst +++ b/protocol/specification/semantics.rst @@ -13,3 +13,4 @@ expected semantics. datainfo classes accessibles + systems diff --git a/protocol/specification/structure.rst b/protocol/specification/structure.rst index 271f789f..38ae0fdf 100644 --- a/protocol/specification/structure.rst +++ b/protocol/specification/structure.rst @@ -27,6 +27,9 @@ interface for interacting with the hardware. Modules usually have one or more **Base classes** assigned that indicate their basic functionality, split into **Interface classes** and **Features**. +Several modules with a tightly coupled functionality can be grouped into +**Systems**. + .. glossary:: Module @@ -60,6 +63,14 @@ basic functionality, split into **Interface classes** and **Features**. specific hierarchy and can be added to any module regardless of interface class. + System + A grouping of modules that interact with predefined semantics and are + tightly coupled to a particular piece of collection of hardware, for + example a power supply or cryomagnet. + + A System, its modules and their API are usually defined in a `YAML + schema ` to facilitate interpretation and automatic checking. + Each of these modules can have static values which are known at startup and dynamic values. These are called **Properties** and **Parameters** respectively. Parameters can in turn have their own Properties. Examples of diff --git a/protocol/specification/systems.rst b/protocol/specification/systems.rst new file mode 100644 index 00000000..f094c6ed --- /dev/null +++ b/protocol/specification/systems.rst @@ -0,0 +1,114 @@ +.. _systems: + +Systems +======= + +See also :ref:`rfc-104`. + +All standard SECoP interface entities described so far (interface classes, +accessibles and so on) refer to a single module. + +However, in many cases, it is not desirable (or even possible) to represent a +complex piece of hardware equipment by a single module. In fact, since SECoP +encourages the use of standard interface classes like `Readable`, the main +"process variables" of the equipment must each be represented by a module's +`value` parameter, while other parameters are used for ancillary information or +configuration of the module. + +The notion of a "system" encompasses a collection of modules that work and +interact in a defined way. + +As always, the definition of a system specifies the *minimum* interface +required, and may contain optional entities. More entities can always be +introduced by each implementation. + +This allows the definition of facility-specific and inter-facility standards for +control and metadata collection beyond the level of "a sensor" or "an analog +output", towards the level of "a cryomagnet". + +System mapping +-------------- + +Like other standard entities, standard systems can be defined by the SECoP +specification. Currently, no such systems are defined. + +A specification designates both the *name* of each required module, and its +*interface* (an interface class, and/or additional accessibles). + +Custom systems can be defined by linking to a schema in the node description, +see :ref:`Schema `. + +The SEC node descriptive data has a node property that lists the systems +contained in it, with a mapping of system-given module names to actual modules +in the node. + +Systems can derive from other systems, and contain other systems as subgroups of +their modules. + +Referencing Systems +------------------- + +In the SECNode descriptive data, the optional property `systems` is introduced. +It is a JSON object with local system names as keys and a description, the +schema name of the system and a mapping of module names as the value. For a +system to be valid, all non-optional modules that are included in the system +definition have to be present. + +Local system names may not clash with module names on the same SEC node. + +Example: + +.. code:: json + + "systems": { + "cryo1": { + "description": "A cryo", + "system": "OrangeCryostat", + "modules": { + "T": "cryo1_T", + "HeLevel": "cryo1_helevel", + }, + }, + } + + +For subsystems: + +.. code:: json + + "systems": { + "mag5t_x": { + "description": "X axis power supply", + "system": "PowerSupply", + "modules": { + "current": "magcur_x", + "voltage": "magvolt_x" + } + }, + "mag5t_y": { + "description": "Y axis power supply", + "system": "PowerSupply", + "modules": { + "current": "magcur_y", + "voltage": "magvolt_y" + } + }, + "mag5t_z": { + "description": "Z axis power supply", + "system": "PowerSupply", + "modules": { + "current": "magcur_z", + "voltage": "magvolt_z" + } + }, + "mag5t": { + "description": "5 Tesla magnet", + "system": "VectorMagnet", + "modules": { + "T": "magtemp", + "X": "mag5t_x", + "Y": "mag5t_y", + "Z": "mag5t_z", + }, + }, + }