SILF Protocol version 1.0 DRAFT¶
Version note¶
This document describes protocol version 1.0.0
Namespaces¶
silf:mode:get
¶
This namespace is used query modes from the experiment.
First client sends:
>>> write(LabdataModeGet(id="query1", type="query"))
<ns0:labdata xmlns:ns0="silf:mode:get" id="query1" type="query" />
Then server responds:
>>> write(LabdataModeGet(id="query1", type="result", suite=ModeSuite(default=Mode("Default mode", "This is the default mode description"))))
<ns0:labdata xmlns:ns0="silf:mode:get" id="query1" type="result">{"default": {"label": "Default mode", "description": "This is the default mode description"}}</ns0:labdata>
Stanza content¶
Contents of silf:mode:get
in type result
are formatted as follows:
{
"mode-keyname": {
"label": "Mode label", "description": "Mode description",
"order" : "1"
},
"mode-keyname-2": {
"label": "Mode label", "description": "Mode description",
"order": "1"
}
}
Each property in this object contains description of one mode, and name of this property is name of the mode.
Modes should be sorded ascending with order
attribute, if order
is equal
sort them alphabetically.
Warning
Before we upgrade experiment software, client should not expect
order
attribute to be defined. If it is undefined sort
it so all input fields with undefined
should be below those
with defined order
.
Backend behaviour
In current implementation experiment does not change state when reclieving this message
Client behaviour
Client allows user to choose mode.
silf:mode:set
¶
This namespace is used to set mode of the experiment, and to return experiment metadata to the users.
This namespace is used query modes from the experiment.
Client sends¶
>>> write(LabdataModeSet(id="query1", type="query", suite=ModeSelection(mode="default")))
<ns0:labdata xmlns:ns0="silf:mode:set" id="query1" type="query">{"mode": "default"}</ns0:labdata>
Code sent by client contains Json object contains single property “mode” and it’s value must be “mode-keyname” (that is name of property under which particular mode is found in silf:mode:get).
Server responds¶
Server responds with metadata containing description of selected mode.
Object will have following properties:
- mode
- name of selected mode — usefull for visitor users
- experimentId
- Globally unique identifier of experiment session
- settings
- Description of user controllable input fields, described in Input fields
- resultDescription
- Description of fields that will present results to the user Output fields
Example response:
{
"experimentId": "urn:uuid:a12e6562-5feb-4046-b98f-d8c40ca1609c",
"mode": "aluminium",
"settings": {
"acquisition_time": {
"live": false, "metadata": {
"label": "Czas pomiaru dla jednej grubo\u015bci materia\u0142u"},
"name": "acquisition_time", "validations": {"min_value": 5.0, "max_value": 600.0}, "type": "interval",
"sort" : "1"},
"light": {"live": false, "metadata": {"label": "O\u015bwietlenie", "style": "light_control"}, "name": "light", "type": "boolean", "sort" : "1"}
},
"resultDescription": {
"time_left": {"name": ["tile_left"], "type": "array", "class": "interval-indicator", "settings": {}, "metadata": {"label": "Czas pozosta\u0142y do ko\u0144ca bierz\u0105cego punktu"}},
"chart": {"name": ["chart"], "type": "array", "class": "chart", "settings": {}, "metadata": {"chart.axis.y.label": "Liczba zlicze\u0144 zarejestrowana przez licznik", "chart.axis.x.label": "Grubo\u015b\u0107 przes\u0142ony [mm]"}
}
}
silf:mode:historical
¶
Has the same contents as silf:mode:set, but sends interface details for historical series.
silf:settings:check
¶
Namespace: silf:settings:check
issed to check settings for validity,
prior to submiting them.
Client sends:
{
"acquisition_time": {"value": 150, "current": false},
"light": {"value": false, "current": false}
}
Property names in this object correspond to appropriate property names
from settings
proprerty in silf:mode:set.
Server responds either with empty tag of type result
or with an error
message (see: Errors).
When user finishes edition of a control (for example when focus is lost)
Client should send values of all controls that were touched by user
in current experiment run, and set current
to true for
control that triggered rsult sending, and to false for all others.
Settings¶
Settings themselves have following properties
value
Value of the settings. Type of the setting varies and is based on type send in silf:mode:set
current
Whether this setting was most recently updated by user. This helps to customise displayed erros and validation, in case of controls that are dependend on each other.
silf:series:start
¶
Sets all the parameters and starts the measurement series, contents sent by the client are the same as for silf:settings:check.
Note
Currently current
property in this stanza is ignored by the server.
But I think it is easier to have the same format (despite
ignored information).
Server response
Server responds either with an error: Errors, or with following structure:
{
"metadata": {"label": "Czas pomiaru 90s."},
"initialSettings": {
"acquisition_time": {"current": false, "value": 90},
"light": {"current": false, "value": false}
},
"seriesId": "urn:uuid:6bd8a024-5a8b-4f04-be84-76dcad89d89f",
"experimentId": "urn:uuid:a12e6562-5feb-4046-b98f-d8c40ca1609c"
}
Where properties have following meaning:
seriesId
- Unique id of current series
experimentId
- Unique id of experiment session to which this series belongs.
metadata
- Dictionary containing additional metadata of the series. For now only key in
this dictionary is series
label
(ie. non-unique human-readable name of the series) initialSettings
- Structure containing settings for the series (as it was set by the user)
silf:series:historical
¶
Has the same contents as silf:series:start but is used by the athena bot to send historical results to the client.
silf:settings:update
¶
Note
It’s a planned feaure and details might change.
During experiment session user my update input fields which are labeled as
live
(see: Input fields). In this case client should send
silf:settings:update
containing only the changed settings.
For example if only light
was changed user should send:
{
"light": {"value": false, "current": true}
}
If settings validate server should respond with
silf:settings:update
containting changed settings. If there are
erros in settings, server should respod with proper error.
silf:results
¶
Results are send as an object, where each result is sent as a distinct property, name of this property is also name of associated result.
So in following example:
{
'sessionId': "urn:uuid:6bd8a024-5a8b-4f04-be84-76dcad89d89f"
'foo' : {value: [1, 2, 3], pragma: "append"}.
'bar' : {value: [1], pragma: "transient"}.
}
two results are sent, one named foo
other named bar
.
Additionaly we send sessionId
property which signifies to which
series this result series belong
Single result¶
Result type has following properties:
pragma
- Controls method in which result series is reconstructed.
value
- Result value
Result series reconstruction¶
Experiment user wants to see whole result series, but in most cases we don’t want to send whole series each time (in some cases we need to!). We also don’t want to send new result stanza for each point if it is unnecessary.
Pragma property defines how series is reconstructed from series of result
messages.
We support following pragmas:
append
Initially experiment series is empty, after each result contents of
value
property is appended to series.For example if we sent following results:
{ "value": [1, 2, 3], "pragma": "append"} { "value": [4, 5], "pragma": "append"}
Series will be reconstructed as: {“value”: [1, 2, 3, 4, 5], “pragma”: “append”}
replace
- Initially experiment series is empty, after reclieving of each result we replace series contents with this result.
transient
- As
append
but will not be stored. Usefull when sending status variables.
silf:results:historical
¶
Has the same contents as as silf:results, but ut is used by the athena bot to send historical results to the client.
silf:series:stop
¶
Stops the series.
User sends following object:
{
"seriesId" : "urn:uuid:6bd8a024-5a8b-4f04-be84-76dcad89d89f"
}
seriesId
property signified series to stop.
Client can omit this seriesId
property.
Experiment responds with the same object:
{
"seriesId" : "urn:uuid:6bd8a024-5a8b-4f04-be84-76dcad89d89f"
}
silf:experiment:stop
¶
Stops the experiment. User sends empty tag to the server.
Structures used in many stanzas¶
Input fields¶
Control fields contain at least following fields:
name
- name of the control, it is not visible to user, but used to in both: silf:settings:check, and silf:series:stop.
type
- Type of data this controls sends.
live
- Boolean value. Currently unused.
metatadata
- A dictionary that contains data
visble to users:
label
Label of conntrol. validations
- Dictionary containing validations ot be done at client side.
default_value
- Default value. It has the same type.
order
Used to sort input fields before they are rendered. Input fields with highter
order
should be presented on top of the input field list. In case of equalorder
fields should be sorted alphabetically onname
attribute.Warning
Before we upgrade experiment software, client should not expect
order
attribute to be defined. If it is undefined sort it so all input fields withundefined
should be below those with definedorder
.
Currently we following types of input fields:
Number control¶
It allows user to submit an integer.
It has following possible validations:
min_value
- minimal value present in the field
max_value
- maximal value present in the field
step
- increment in which to go from
min_value
tomax_value
Value rendered to JSON Format¶
Client should create values that are json number objects, or dscimal strings.
{
"number_control": {"value": 150, "current": false},
"number_control_2": {"value": "36", "current": false}
}
Example of serialized control:
>>> control = NumberControl("foo", "Enter a number")
>>> control.to_json_dict() == {
... 'type': 'number', 'name': 'foo',
... 'metadata': {'label': 'Enter a number'},
... 'live': False}
True
>>> control.min_value = 1
>>> control.max_value = 10
>>> control.to_json_dict() == {
... 'type': 'number',
... 'validations': {'min_value': 1, 'max_value': 10},
... 'live': False,
... 'metadata': {'label': 'Enter a number'}, 'name': 'foo'}
True
Boolean control¶
It allows user to submit an boolean value.
Value rendered to JSON Format¶
Client should create values that are json boolean objects (any other objects
will be passed to bool
function.
{
"number_control": {"value": 150, "current": false},
"number_control_2": {"value": "36", "current": false}
}
Time interval control¶
Allows student to submit amount of time.
{
"timedelta_control": {"value": 150, "current": false}
}
It has following validations:
min_value
- minimal amout of time student could send. In the same format as it is send from client as settings.
max_value
- maximal amount of time student can send.
Value rendered to JSON Format¶
Client should send to server amount of seconds (possibly as a float value).
ComboBox control¶
Renders a combo box.
It has no additional properties, but metadata
property must contain
choices
property containing object defining the combo box.
Keys in the choices object define values that may will be sent from this controls, and values are user readable labels.
Example:
{
'type': 'combo-box',
'live': False,
'metadata': {
'label': 'Select material',
'choices': {
'lead': 'Use lead aperture',
'cu': 'Use cooper aperture'
}
},
'name': 'material',
'default_value': 'cu'
}
This control would be rendered as a ComboBox with two choices:
Use lead aperture
and Use cooper aperture
. And if user would choose
Use cooper aperture
, this control would send:
{
...
'material: 'cu',
...
}
Output fields¶
Set of output fields is a plain object, each property denotes one output field, name of the property.
This block defines two output fields named foo
and bar
.
{
'foo': {'name': ['some_result'], ... },
'bar': {'name': ['other_result'], ... }
}
Format of object desceibing single output fields is defined in the next section.
Definitionamen of single output field¶
Output fields have following attributes:
name
names of result fields this output consumes. It is an array of strings.
Warning
Warning this is unimplemented in GUI,
names
is ignored, and follwing logic is used:If experiment reclieves:
{ 'foo': {'name': ['bar'], ... }, 'baz': {'name': ['foobar'], ... } }
Control that is under property
foo
will display results from propertyfoo
(and notbar
asname
would indicate).This will be fixed sometime!
Until then Python API disallows sending
name
that is different than control name. So currently writen code is future proof.type
- Type of the resul field. This attribute defines how this field works. A string.
class
- HTML class of result. This defines how does this field look. A string.
metadata
- Dictionary od properties of this field that are visible
settings
- Dictionary od properties of this field that are not visible to user
Applicable classes, and their behaviour¶
For now following classes are understood by the client.
Indicators, that display only the newest measurement in the series:
interval-indicator
- Renders incoming data as a time interval, signifying (for example) time left end of current measurement point. It requires for
integer-indicator
- Renders a number, for example number of registered counts on geiger counter.
Other classes:
chart
- A chart.
Indicator example¶
Example of serialized indicator:
{
'class': 'integer-indicator',
'metadata': {'label': 'Current voltage [V]'},
'name': ['current_voltage'],
'settings': {},
'type': 'array'
}
Chart example¶
Example of serialized chart:
{
'class': 'chart',
'metadata': {'chart.axis.x.label': 'Voltage between GM electrodes',
'chart.axis.y.label': 'Counts in given time interval',
'label': 'GM Counter characteristics'},
'name': ['chart'],
'settings': {},
'type': 'array'}
How are results send and displayed¶
Each output field defines from which result field (or fields) it pulls the
results, this defined in the name
property.
Errors¶
Results are send as an object with single property errors
that contains
a list of error objects.
Each error object has following properties:
severity
- A string describing how severe is this error. Following values are
acceptable:
error
,warning
,info
. error_type
- A string. Following values are accetable:
device
,user
. If value isuser
it means that user generated this error, and (so) can be fixed,device
means that there is some error in the device. metadata
Object with other error info:
message
- Message for user
field
- If it is present it is the name of an input field that is cause of this error (used when validating input fields).
Example:
{'errors':[
{
'severity':'error',
'error_type': 'user',
'metadata':{
'message': 'Invalid value in field foo',
'field': 'foo',
},{
'severity':'error',
'error_type': 'user',
'metadata':{
'message': 'Invalid value in field bar',
'field': 'bar',
}
])