Remove obsolete protocol specification
The one at https://www.github.com/SampleEnvironment/SECoP is the correct version! Change-Id: I4f8a9c3b40ea4e1f3ecea8b7b491dd96cb04d009 Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/21437 Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de> Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de> Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
parent
2d646f1af4
commit
536c798699
@ -1,12 +1,14 @@
|
||||
Welcome to SECoP's documentation!
|
||||
=================================
|
||||
Welcome to FRAPPY documentation!
|
||||
================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
protocol/index
|
||||
playground/index
|
||||
|
||||
server/index
|
||||
client/index
|
||||
framework/index
|
||||
gui/index
|
||||
facility/index
|
||||
|
||||
|
||||
Indices and tables
|
||||
|
@ -1,13 +0,0 @@
|
||||
Playground documentation
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
server/index
|
||||
client/index
|
||||
framework/index
|
||||
gui/index
|
||||
facility/index
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
SECoP Encoding
|
||||
==============
|
||||
|
||||
.. automodule:: secop.protocol.encoding.secop
|
||||
:members:
|
||||
|
@ -1,7 +0,0 @@
|
||||
Demo
|
||||
====
|
||||
|
||||
.. automodule:: secop.protocol.framing.demo
|
||||
:members:
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
EOL
|
||||
===
|
||||
|
||||
.. automodule:: secop.protocol.framing.eol
|
||||
:members:
|
||||
|
@ -1,11 +0,0 @@
|
||||
Framings
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
demo
|
||||
eol
|
||||
null
|
||||
rle
|
||||
|
@ -1,6 +0,0 @@
|
||||
Null
|
||||
====
|
||||
|
||||
.. automodule:: secop.protocol.framing.null
|
||||
:members:
|
||||
|
@ -1,6 +0,0 @@
|
||||
RLE
|
||||
===
|
||||
|
||||
.. automodule:: secop.protocol.framing.rle
|
||||
:members:
|
||||
|
@ -1,22 +0,0 @@
|
||||
Commands
|
||||
========
|
||||
|
||||
The "done" message should be returned quickly, the time scale should
|
||||
be in the order of the time needed for communications. Actions which have
|
||||
to wait for physical changes, can be triggered with a command.
|
||||
The information about the success of such an action has to be transferred
|
||||
via parameters, namely the status parameter.
|
||||
|
||||
A command has at least the following properties:
|
||||
|
||||
:description:
|
||||
tell what this command does
|
||||
|
||||
:arguments:
|
||||
a list of datatypes for the command arguments (may be empty)
|
||||
|
||||
:resulttype:
|
||||
the type of the result (may be null)
|
||||
|
||||
|
||||
|
@ -1,173 +0,0 @@
|
||||
Datatypes
|
||||
=========
|
||||
|
||||
double
|
||||
------
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["double"] *or*
|
||||
| ["double", <min>] *or*
|
||||
| ["double", <min>, <max>]
|
||||
|
|
||||
| if <max> is not given or null, there is no upper limit
|
||||
| if <min> is null or not given, there is no lower limit
|
||||
|
||||
* - Transport example
|
||||
- | 3.14159265
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | double
|
||||
|
||||
int
|
||||
---
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["int"] *or*
|
||||
| ["int", <min>] *or*
|
||||
| ["int", <min>, <max>]
|
||||
|
|
||||
| if <max> is not given or null, there is no upper limit
|
||||
| if <min> is null or not given, there is no lower limit
|
||||
|
||||
* - Transport example
|
||||
- | -55
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | int64_t
|
||||
|
||||
bool
|
||||
----
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["bool"]
|
||||
|
||||
* - Transport example
|
||||
- | true
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | int64_t
|
||||
|
||||
|
||||
enum
|
||||
----
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["enum", {<name> : <value>, ....}]
|
||||
|
||||
* - Transport example
|
||||
- | 2
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | int64_t
|
||||
|
||||
|
||||
string
|
||||
------
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["string"] *or*
|
||||
| ["string", <max len>] *or*
|
||||
| ["string", <max len>, <min len>]
|
||||
|
|
||||
| if <max len> is not given, it is assumed as 255.
|
||||
| if <min len> is not given, it is assumed as 0.
|
||||
| if the string is UTF-8 encoded, the length is counting the number of bytes, not characters
|
||||
|
||||
* - Transport example
|
||||
- | "hello!"
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | char \*
|
||||
|
||||
blob
|
||||
----
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["blob", <max len>] *or*
|
||||
| ["blob", <max len>, <min len>]
|
||||
|
|
||||
| if <min len> is not given, it is assumed as 0.
|
||||
|
||||
* - Transport example
|
||||
- | "AA==" (base64 encoded)
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | struct {int64_t len, char \*data}
|
||||
|
||||
array
|
||||
-----
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["array", <basic type>, <max len>] *or*
|
||||
| ["array", <basic type>, <max len>, <min len>]
|
||||
|
|
||||
| if <min len> is not given, it is assumed as 0.
|
||||
| the length is the number of elements
|
||||
|
||||
* - Transport example
|
||||
- | [3,4,7,2,1]
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | <basic_datatype>[]
|
||||
|
||||
tuple
|
||||
-----
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["tuple", [<datatype>, <datatype>, ...]]
|
||||
|
||||
* - Transport example
|
||||
- | [0,"idle"]
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | struct
|
||||
|
||||
struct
|
||||
------
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["struct", {<name> : <datatype>, <name>: <datatype>, ....}]
|
||||
|
||||
* - Transport example
|
||||
- | {"x": 0, "y": 1}
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | struct
|
||||
|
|
||||
| might be null
|
@ -1,11 +0,0 @@
|
||||
Structure of the descriptive json
|
||||
=================================
|
||||
|
||||
* json = {"modules": <list_of_modules>, "properties": <list_of_sec-node_properties>, ...}
|
||||
* module = {"name": <name_of_module>, "parameters": <list_of_parameters>, "commands": <list_of_commands>, "properties": <list_of_module_properties>}
|
||||
* parameter = {"name": ..., "properties": <list_of_properties>}
|
||||
* command = {"name": ..., "properties": <list_of_properties>}
|
||||
* property = {"name":<name>, "datatype": <datatype>, "value": <value>}
|
||||
|
||||
note: property may also be [<name>,<datatype>,<value>]
|
||||
|
@ -1,48 +0,0 @@
|
||||
Descriptive properties
|
||||
======================
|
||||
|
||||
Mandatory descriptive properties
|
||||
--------------------------------
|
||||
|
||||
parameter-properties
|
||||
++++++++++++++++++++
|
||||
|
||||
* name (implicit)
|
||||
* datatype
|
||||
* readonly (bool)
|
||||
|
||||
module-properties
|
||||
+++++++++++++++++
|
||||
|
||||
* interface_class [list_of_strings] (MAY be empty)
|
||||
|
||||
SEC-Node-properties
|
||||
+++++++++++++++++++
|
||||
|
||||
* no mandatory properties
|
||||
|
||||
Optional descriptive properties
|
||||
-------------------------------
|
||||
|
||||
parameter-properties
|
||||
++++++++++++++++++++
|
||||
|
||||
* unit (string), SHOULD be given if meaningful (if not given: unitless) (empty string: unit is one)
|
||||
* description (string), SHOULD be given
|
||||
* visibility
|
||||
* group (identifier) (MUST start with an uppercase letter) (if empty string: treat as not specified)
|
||||
|
||||
module-properties
|
||||
+++++++++++++++++
|
||||
|
||||
* description (string), SHOULD be given
|
||||
* visibility
|
||||
* group (identifier) (MUST start with an uppercase letter) (if empty string: treat as not specified)
|
||||
* meaning ???
|
||||
* importance ???
|
||||
|
||||
SEC-Node-properties
|
||||
+++++++++++++++++++
|
||||
|
||||
* description (string), SHOULD be given
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.4 KiB |
@ -1,8 +0,0 @@
|
||||
Heartbeat
|
||||
=========
|
||||
* ping gets an 'intended looptime' argument (as number in seconds or null to disable)
|
||||
* server replys as usual
|
||||
* if the server received no new message within twice the indended looptime, it may close the connection.
|
||||
* if the client receives no pong within 3s it may close the connection
|
||||
* later discussions showed, that the ping/pong should stay untouched and the keepalive time should be (de-)activated by a special message instead. Also the 'connection specific settings' from earlier drafts may be resurrected for this....
|
||||
|
@ -1,9 +0,0 @@
|
||||
Hirarchy
|
||||
========
|
||||
|
||||
* group property (currently a identifier like string, may be extended to tree like substrucutres by allowing ':')
|
||||
* visibility (enum(3:expert, 2:advanced, 1:user)) (default to 1 if not given)
|
||||
if visibility is set to user: everybody should see it
|
||||
if visibility is set to advanced: advanced users should see it
|
||||
if visibility is set to expert: only 'experts' should see it
|
||||
|
@ -1,73 +0,0 @@
|
||||
History
|
||||
=======
|
||||
|
||||
Meeting 29.5.2017
|
||||
-----------------
|
||||
|
||||
* for api: float is 'double'
|
||||
* everything countable is int64_t
|
||||
* description is string (UTF-8 without embedded \0) (zero terminated for API)
|
||||
* names / identifiers are: [_a-z][_a-z0-9]{0,63}
|
||||
* BLOB is [length, string_encoding (base64 or json_string) ] ???
|
||||
* enum is transferred by value (api: int64_t)
|
||||
* basic data types: string, BLOB(maxsize), int, double, bool, enum(mapping)
|
||||
* encode as ["string"] ["blob"] ["int"] ["double"] ["bool"] ["enum", {<number_value>:<name>}]
|
||||
* send as json_string [length, json_string] number number 0_or_1 number_value
|
||||
* complex data types: array, tuple, struct
|
||||
* encode as: ["array", <subtype>] ["tuple", [<list_of_compositing data types>] ["struct", {"name_of_subcomponent":<type of subcomponent>}]
|
||||
* send as [array] [array} {mapping}
|
||||
* forbid: structs in structs, nesting level > 3, arrays may only contain basic types + tuple
|
||||
* essential features should not rely on complex data types
|
||||
* fallback: if ECS can not handle a non-basic datatype: handle as string containing the JSON-representation.
|
||||
* mandatory for all ECS: enum, int, double, string, bool, tuple(enum,string)
|
||||
|
||||
Merge datatype and validator
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
* ["enum", {<number_value>:<json_string>}]
|
||||
* ["int"] or ["int", <lowest_allowed_value>, <highest_allowed_value>]
|
||||
* ["double"] or ["double", <lowest_allowed_value>, <highest_allowed_value>]
|
||||
* ["bool"]
|
||||
* ["blob", <maximum_size_in_bytes>] or ["blob", <minimum_size_in_bytes>, <maximum_size_in_bytes>]
|
||||
* ["string", <maximum_allowed_length>] or ["string", <min_size>, <max_size>]
|
||||
* ["array", <basic_data_type>, <max_elements>] or ["array", <dtype>, <min_elements>, <max_elements>]
|
||||
* ["tuple", [ <list_of_dtypes ]]
|
||||
* ["struct", { <name_of_component_as_json_string>:<dtype>}]
|
||||
|
||||
Examples
|
||||
++++++++
|
||||
|
||||
* status: ["tuple", [ ["enum", {0:"init", 100:"idle", 200:"warn", 300:"busy"}], ["string", 255] ] ]
|
||||
* p/pi/pid-triple: ["array", ["double", 0, 100], 1, 3]
|
||||
|
||||
|
||||
Meeting 30.5.2017
|
||||
-----------------
|
||||
|
||||
* data values can be transferred as json_null, meaning: no value yet
|
||||
* json_null can not be used inside structured data types
|
||||
* property name for datatype is "datatype"
|
||||
|
||||
Meeting 11.9.2017
|
||||
-----------------
|
||||
|
||||
Merge datatype and validator
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
* enum, int, double, bool, tuple, struct as before
|
||||
* ["blob", <maximum_size_in_bytes>] or ["blob", <maximum_size_in_bytes>, <minimum_size_in_bytes>]
|
||||
* ["string", <maximum_allowed_length>] or ["string", <max_size_in_bytes>, <minimum_size_in_bytes>]
|
||||
* ["array", <basic_data_type>, <max_elements>] or ["array", <dtype>, <max_elements>, <min_elements>]
|
||||
|
||||
|
||||
Interface_class
|
||||
+++++++++++++++
|
||||
|
||||
* Drivable, Writable, Readable, Module (first character uppercase, no middle 'e')
|
||||
|
||||
|
||||
transfer_of_blob
|
||||
++++++++++++++++
|
||||
|
||||
* transport-encoding as base64-encoded string (no prefixed number of bytes....)
|
||||
|
@ -1,22 +0,0 @@
|
||||
Protocol documentation
|
||||
======================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
motivation
|
||||
secop_v2017-09-14
|
||||
issue_1
|
||||
issue_2
|
||||
issue_3
|
||||
issue_4
|
||||
issue_5
|
||||
issue_6
|
||||
issue_7
|
||||
issue_8
|
||||
issue_9
|
||||
issue_10
|
||||
outdated
|
||||
history
|
||||
meeting_2017_11_27
|
||||
|
@ -1,27 +0,0 @@
|
||||
SECoP Issue 1: About SECoP Issues
|
||||
=================================
|
||||
|
||||
The idea behind SECoP Issues is to document properly what was proposed,
|
||||
what was discussed, what was decided and why it was decided.
|
||||
|
||||
An issue might take different states:
|
||||
|
||||
proposed
|
||||
--------
|
||||
|
||||
A proposal should contain the motivation. As long as nobody else
|
||||
joins into a discussion, the state remains *proposed*
|
||||
|
||||
under discussion
|
||||
----------------
|
||||
|
||||
This state is kept until there is a decision taken.
|
||||
|
||||
closed
|
||||
------
|
||||
|
||||
After a decision the state is *closed*. The issue is not deleted,
|
||||
even if the decision was to not follow further the proposal.
|
||||
This is helpful if somebody later rises a similar issue.
|
||||
However, it should be possible to reopen an issue, if new
|
||||
arguments arise.
|
@ -1,45 +0,0 @@
|
||||
SECoP Issue 10: Character set for Names (under discussion)
|
||||
==========================================================
|
||||
|
||||
Uppercase Characters in Identifiers
|
||||
-----------------------------------
|
||||
|
||||
Actually (V2017-09-14), the following is specified;
|
||||
|
||||
The identifiers are composed by
|
||||
lowercase ascii letters, digits and underscore, where a digit may not
|
||||
appear as the first character. Identifiers starting with underscore are
|
||||
reserved for special purposes like internal use for debugging. The
|
||||
identifier length is limited (<=63 characters).
|
||||
|
||||
In the outdated part of the documentation (`outdated Messages`_) it is not
|
||||
explicitly stated, that identifiers have to be lower case, and also
|
||||
in some of the running examples contain uppercase identifiers.
|
||||
|
||||
.. _`outdated Messages`: messages.html
|
||||
|
||||
Discussion
|
||||
~~~~~~~~~~
|
||||
|
||||
Markus:
|
||||
For me, it is not that important, if uppercase characters are allowed or not, but,
|
||||
identifiers must be unique independent of case, i.e. it is not allowed to have two
|
||||
different modules "t" and "T", on a SEC node. And we should take a decision soon.
|
||||
|
||||
Default parameters 'value' and 'target'
|
||||
---------------------------------------
|
||||
|
||||
In the implementation, in the "read" and "update" messages "<module>:value" can be just
|
||||
replaced by "<module>", and in "change" and "changed" message "<module>:target" can
|
||||
be replaced by "<module>".
|
||||
|
||||
Discussion
|
||||
~~~~~~~~~~
|
||||
|
||||
Markus:
|
||||
I prefer not to allow these shortcuts. We also have to distinguish module properties
|
||||
from properties of the module parameter 'value'.
|
||||
|
||||
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
SECoP Issue 2: Equipment ID in Describing Message (under discussion)
|
||||
====================================================================
|
||||
|
||||
The equipment ID is a SEC node property, and it is therefore redundant
|
||||
to put it as the second item of the describe message.
|
||||
|
||||
However as the describe/describing message might be extended later, for
|
||||
example to get the description of single modules only, we should specify
|
||||
a fixed word for the second item of the describe message, for example the
|
||||
keyword "ALL" or "All".
|
||||
|
||||
At the meeting in Berlin (2017-05-30) this was discussed, but it was not
|
||||
yet decided the the keyword should be exactly. Until a final decision,
|
||||
SECoP clients should ignore the second item.
|
||||
|
||||
Opinions
|
||||
--------
|
||||
|
||||
We should use key keyword ALL (Markus Zolliker)
|
||||
|
||||
Decision
|
||||
--------
|
@ -1,47 +0,0 @@
|
||||
SECoP Issue 3: SECoP Timestamp Format (closed)
|
||||
==============================================
|
||||
|
||||
Proposals for the timestamp format are:
|
||||
|
||||
ISO time format
|
||||
---------------
|
||||
|
||||
A date+time string in ISO format like "2017-06-21T13:30:01.123456+02:00"
|
||||
|
||||
The fractional seconds are optional, but the timezone has to be given. Z is allowed instead of +00:00.
|
||||
|
||||
Advantages:
|
||||
|
||||
* human readable
|
||||
|
||||
Disadvantages:
|
||||
|
||||
* needs more conversion efforts, as the time is internally already stored as numbers on mosts systems (supporting math operations).
|
||||
* although the ISO standard is clearly defined, there is a risk that time zones and daylight saving time is not handled properly
|
||||
|
||||
Fractional Unix Time
|
||||
--------------------
|
||||
|
||||
Seconds since 1970-01-01T00:00:00+00:00, represented as a number. When converted to a IEEE double, a resolution of 1 usec can be kept for dates up to 2112.
|
||||
|
||||
Advantages:
|
||||
|
||||
* if a double is used as an internal representation, no conversion is needed. using a double as an internal time representation has the advantage, that math operations can be done for free.
|
||||
* relative times for systems with no synchronized clock can be represented easily
|
||||
|
||||
Disadvantages:
|
||||
|
||||
* not human readable (or at least not easily: time differences in seconds are still visible)
|
||||
|
||||
|
||||
Discussion
|
||||
----------
|
||||
|
||||
1) Human readibility was judged less important than easy implementaion by the majority.
|
||||
|
||||
2) Implementing relative times is also easier.
|
||||
|
||||
Decision
|
||||
--------
|
||||
|
||||
At the meeting in Berlin (2017-05-30) the attendes decided for "Fractional Unix Time".
|
@ -1,18 +0,0 @@
|
||||
SECoP Issue 4: Timeout (under discussion)
|
||||
=========================================
|
||||
|
||||
For a SECoP client, in order to detect that a connection to a SECoP server is dead,
|
||||
'ping' messages can be sent. When no 'pong' message is received within a specified
|
||||
time, then the client can consider the connection as dead.
|
||||
|
||||
If the server does not specify a the SEC node property 'timeout', the timeout
|
||||
is assumed to be 3s.
|
||||
|
||||
Opinions
|
||||
--------
|
||||
|
||||
On the meeting in Garching (2017-09-14) it was proposed to fix this a standard.
|
||||
|
||||
|
||||
Decision
|
||||
--------
|
@ -1,34 +0,0 @@
|
||||
SECoP Issue 5: Definition of the term 'Property' (under discussion)
|
||||
===================================================================
|
||||
|
||||
The definition as in SECoP V2016-11-30 draft is not very consistent.
|
||||
|
||||
As decriptive data we have:
|
||||
|
||||
- SEC node properties
|
||||
- module properties
|
||||
- parameters properties
|
||||
- command properties
|
||||
|
||||
Live data may be:
|
||||
- value
|
||||
- timestamp 't'
|
||||
- sigma 'e'
|
||||
|
||||
It is confusing to use the same term 'property' for live data and for
|
||||
descriptive data.
|
||||
|
||||
The section with the definition of properties has to be rewritten.
|
||||
|
||||
Opinions
|
||||
--------
|
||||
|
||||
Enrico proposed to name live data like timestamps and sigma 'qualifiers'.
|
||||
|
||||
Markus supports this. He would be happy also with an other term than
|
||||
'qualifiers', but definitely does not like the terms 'live properties' and
|
||||
'descriptive properties', as two different things share the same name.
|
||||
|
||||
|
||||
Decision
|
||||
--------
|
@ -1,23 +0,0 @@
|
||||
SECoP Issue 6: Keep Alive (under discussion)
|
||||
============================================
|
||||
|
||||
For a SECoP server, in order to detect that a client connection is dead,
|
||||
it might close a connection with no messages within a defined period of time.
|
||||
|
||||
The discussed mechanism is:
|
||||
|
||||
The SECoP client has to set the connection parameter 'keepalive' to a value
|
||||
representing the number of seconds it will send 'ping' (or other) messages.
|
||||
The SECoP server can close connections with no messages for a time period
|
||||
well above this value (more than 10% higher).
|
||||
|
||||
Opinions
|
||||
--------
|
||||
|
||||
Markus proposes to mention the 10 % in the specification.
|
||||
It should also be mentioned, that for keeping the connection alive
|
||||
any message might be sent instead of the ping message.
|
||||
|
||||
|
||||
Decision
|
||||
--------
|
@ -1,24 +0,0 @@
|
||||
SECoP Issue 7: Time Synchronization (under discussion)
|
||||
======================================================
|
||||
|
||||
As a SECoP server and a SECoP client might not run with a common clock,
|
||||
the SECoP client should be able to correct for time slips.
|
||||
|
||||
The recommended mechanism is (proposal by Markus):
|
||||
|
||||
After connecting to a server, the client records its internal time before sending
|
||||
a ping request.
|
||||
|
||||
If the pong request does not contain a timestamp,
|
||||
the client knows, that the SEC node does not provide timestamps and
|
||||
therefore it has to create timestamps on the time of reception of messages.
|
||||
|
||||
If the returned timestamp lies between the time the ping message was sent and the
|
||||
time the pong message was received, it does not need to correct the timestamps.
|
||||
|
||||
If not, the average of the 'ping' time and the 'pong' time is calculated and
|
||||
the difference to the received timestamp is used for correcting further
|
||||
timestamps.
|
||||
|
||||
On the meetings in Berlin and Garching in 2017 it was proposed to put this into
|
||||
the standard, the exact wording has to be decided.
|
@ -1,15 +0,0 @@
|
||||
SECoP Issue 8: Groups (under discussion)
|
||||
========================================
|
||||
|
||||
Proposal
|
||||
--------
|
||||
|
||||
Modules as well as parameters may have a property "group".
|
||||
If the client has the possibility to group modules and/or
|
||||
parameters, it should use this information for grouping.
|
||||
|
||||
Groups must start with uppercase letters.
|
||||
|
||||
The "group" property may contain colons (':') as separator,
|
||||
in order to construct a hierarchy of more than one level.
|
||||
|
@ -1,39 +0,0 @@
|
||||
SECoP Issue 9: Module Meaning (under discussion)
|
||||
================================================
|
||||
|
||||
meaning
|
||||
-------
|
||||
|
||||
For the ECS an automatic detection of the main modules would be desirable.
|
||||
|
||||
For example a SEC Node could tell which sensor would be the closest one to
|
||||
the sample, which should be registered in the ECS as the sample temperature.
|
||||
|
||||
For this, a module property "meaning" is proposed. This can get one of the
|
||||
following values:
|
||||
|
||||
* sample_temperature
|
||||
* magnetic_field
|
||||
|
||||
importance
|
||||
----------
|
||||
|
||||
But what to do, if several modules claim to be the sample temperature?
|
||||
There might be a SEC node controlling cryostat, which has a sample temperature sensor,
|
||||
but another SEC node controlling an insert with a sample sensor. As the insert
|
||||
is put into the cryostat, we declare the cryostat to have importance=1 and
|
||||
the insert an importance=2. To resolve the ambiguity, the ECS chooses the
|
||||
module with the highest importance to be labelled as the read sample temperature.
|
||||
|
||||
Proposal:
|
||||
|
||||
predefined importance:
|
||||
|
||||
* importance=1 for a device which can not be inserted or added to another one
|
||||
* importance=2 for a device which can be inserted into an other one
|
||||
|
||||
Higher values are to be used when an additional device may be inserted into an insert
|
||||
and the like.
|
||||
|
||||
We should allow importance to be a floating point number, in case later a value
|
||||
between 1 and 2 has to be used.
|
@ -1,92 +0,0 @@
|
||||
JSON structure
|
||||
==============
|
||||
|
||||
> Mit JSON Freeze meine ich nur Arrays von Objekten also:
|
||||
> -Node hat ein Array von Properties und ein Array von Modulen
|
||||
> -Module haben ein Array von Properties, ein Array von Parametern und ein Array von Commands
|
||||
> -Parameter und Commands haben jeweils ein Array von Properties
|
||||
|
||||
node = { 'properties' : [<property>],
|
||||
'modules' : [<module>] }
|
||||
|
||||
module = { 'properties' : [<property>],
|
||||
'parameter' : [<parameter>],
|
||||
'commands' : [<command>] }
|
||||
|
||||
parameter = { 'properties' : [<property>] }
|
||||
|
||||
commands = { 'properties' : [<property>] }
|
||||
|
||||
property = { 'property-name' : 'property-value' }
|
||||
|
||||
|
||||
ODER
|
||||
----
|
||||
|
||||
node = [ <array_of_properties>, <array_of_modules> ]
|
||||
|
||||
array_of_modules = [ <module>, ... ]
|
||||
|
||||
module = <array_of_properties>, <array_of_params>, <array_of_commands>
|
||||
#OR#
|
||||
module = [<array_of_properties>, <array_of_params>, <array_of_commands>]
|
||||
|
||||
array_of_params = [ <param>, ...]
|
||||
|
||||
param = <array_of_properties>
|
||||
|
||||
array_of_commands = [ <command>, ...]
|
||||
|
||||
command = < array_of_properties>
|
||||
|
||||
array_of_properties = [ <property>, ...]
|
||||
|
||||
property = 'name', 'value'
|
||||
#OR#
|
||||
property = ['name', 'value']
|
||||
#OR#
|
||||
property = {'name' : 'value'}
|
||||
|
||||
Oder ganz anders?
|
||||
|
||||
Siehe auch diskussion im HZB-wiki hierzu....
|
||||
|
||||
verwirrend....
|
||||
|
||||
vorerst folgende Festlegung:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{"equipment_id": "cryo_7",
|
||||
"firmware": "The SECoP playground",
|
||||
"modules": ["cryo", {"commands": ["stop", {"resulttype": "None",
|
||||
"arguments": "[]",
|
||||
"description": "Testing command implementation\\n\\nwait a second"
|
||||
},
|
||||
"start", {"resulttype": "None",
|
||||
"arguments": "[]",
|
||||
"description": "normally does nothing,\\n\\nbut there may be modules which _start_ the action here\\n"
|
||||
}
|
||||
],
|
||||
"group": "very important/stuff",
|
||||
"implementation": "secop.devices.cryo.Cryostat",
|
||||
"interfaces": ["Drivable", "Readable", "Device"],
|
||||
"parameters": ["status", {"readonly": true,
|
||||
"datatype": ["tuple", ["enum", {"unknown":-1,"idle":100, "warn":200, "unstable":250, "busy":300,"error":400}], "string"],
|
||||
"description": "current status of the device"
|
||||
},
|
||||
"value", {"readonly": true,
|
||||
"datatype": ["double",0,null],
|
||||
"description": "regulation temperature",
|
||||
"unit": "K"
|
||||
},
|
||||
"target", {"readonly": false,
|
||||
"datatype": ["double",0,null],
|
||||
"description": "target temperature",
|
||||
"unit": "K"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": "2017.01"
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
Meeting at PSI 2017.11.27 - 2017.11.29
|
||||
======================================
|
||||
|
||||
participants:
|
||||
* Eddy Lelievre-Berna
|
||||
* Klaus Kiefer
|
||||
* Markus Zolliker
|
||||
* Anders Petterson
|
||||
* Niklas Ekström
|
||||
* Lutz Rossa
|
||||
* Frank Wutzler
|
||||
* Enrico Faulhaber
|
||||
|
||||
.. contents:: Inhaltsverzeichnis
|
||||
:local:
|
||||
:depth: 2
|
||||
|
||||
27.11.2017
|
||||
++++++++++
|
||||
|
||||
Agenda topic: general remarks
|
||||
-----------------------------
|
||||
|
||||
perception of SECoP seems suboptimal therefore we want to
|
||||
|
||||
* create an forum on the ISSE webpage (+linking to the documentation)
|
||||
* update/rewrite the documentation first
|
||||
* provide a SHORT overview of SECoP (max 2 pages, no details)
|
||||
* provide a readonly copy of SECoP on github (or other PUBLIC site)
|
||||
|
||||
* Eddy mentions some critisism (by others), that information about SECoP was difficult or not at all to be found.
|
||||
|
||||
.. todo::
|
||||
An new, short overview shall be created by HZB (i.e. Frank)
|
||||
|
||||
|
||||
SECoP from our point of view:
|
||||
|
||||
* self describing protocol to control hardware
|
||||
* flexible, modular
|
||||
* unifying the big number of existing, incompatible (proprietary) protocols, for which often not even an API is provided
|
||||
* provides an api
|
||||
* wants to achieve interoperability between facilities
|
||||
|
||||
.. todo::
|
||||
All committee members should be contributors to the SECoP github project
|
||||
|
||||
|
||||
Agenda topic: discussion about issues
|
||||
-------------------------------------
|
||||
|
||||
* Markus created the Issues, everybody likes the approach
|
||||
* a discussion about the different ways to handle tickets/issues with redmone/github/in a repo ensures.
|
||||
* the discussion broadens about documentation/issue change tracking, rights for modification/merge
|
||||
|
||||
.. todo::
|
||||
result is: we try to use the github workflow for documentation (as wiki) and issues (as topics)
|
||||
|
||||
Agenda topic: HZB SECoP dll: current status
|
||||
-------------------------------------------
|
||||
|
||||
* programmatic creation of SEC-nodes via CreateNode, AddModule, AddParameter, AddCommand, AddProperty
|
||||
* finalise with NodeComplete (also enable access from outside)
|
||||
* builds a multithreaded server for each Node, each Module is handled by it's own thread
|
||||
* building keeps an internal state and should be singlethreaded!
|
||||
* Variant data type (with unit tests) implemented in a C compliant way
|
||||
* LabVIEW test case (calling the DLL from LabVIEW) working
|
||||
* view issues left: (note: still prototype!)
|
||||
* closedown with non-QT application sometimes crashes
|
||||
* validation not yet 100% complete
|
||||
* refactoring
|
||||
* live demo of a needle valve controller controlled by a small LabVIEW demo programm emebdding the dll, beeing controlled by a simple network client (entering secop protocol messages by hand)
|
||||
* accesscontrol can be done via multiple nodes exporting a (posible readonly) subset of modules/parameters
|
||||
|
||||
New problems found:
|
||||
1) not all json libraries accept plain json-values like '1.234', but only json-documents
|
||||
2) concentrate on the 'working' ones
|
||||
3) open an issue for this (for documenting this)
|
||||
4) a way out could be to jsonify the whole message, if we would ever need it
|
||||
5) Lutz found a (workaround) way to handle this:
|
||||
* while reading a SECoP value (JSON value), the code surrounds the value with brackets ('[' value ']'), reads it with its library and takes the first element
|
||||
* when writing a SECoP value, you generate a JSON array of one element, convert it with the JSON library to a string and remove the surrounding brackets.
|
||||
|
||||
.. todo::
|
||||
create an Issue to document this.
|
||||
|
||||
Discussion about access control:
|
||||
|
||||
* currently SECoP itself does not provide access control (except read/write property)
|
||||
* we rely on existing network solutions (bind to local port, use SSL Server, use multiple 'view' nodes)
|
||||
* agreement, that access control is not part of SECoP
|
||||
|
||||
.. todo::
|
||||
open an closed issue documenting this discussion
|
||||
|
||||
|
||||
Agenda Topic: Issues inside the playground-protocol-documentation
|
||||
-----------------------------------------------------------------
|
||||
|
||||
* overview of the current Issues
|
||||
|
||||
.. note::
|
||||
* a lengthy discussion about how to proceed ensures
|
||||
* followed by a discussion about delayed change/commit of parameters, changing multiple parameters 'at once'
|
||||
* discussing commons and differences between start, pause, continue and stop
|
||||
* discussion is postponed without result
|
||||
|
||||
.. todo::
|
||||
create an Issue for starting or synchronizing disjunct hw-modules (possible delegated to other SEC-Nodes)
|
||||
|
||||
.. todo::
|
||||
create an Issue to collect uses case for:
|
||||
* different kinds of HW (different parameter setting with respect to starting)
|
||||
|
||||
.. todo::
|
||||
create an Issue (to be discussed) for:
|
||||
* reading the (RO) target parameter gives you the HW value
|
||||
* if there is no start command available, writing to the (RW) wanted_target starts the action
|
||||
else you need to call start() after writing to wanted_target.
|
||||
In any case, the target parameter reflects the value used by the hw.
|
||||
|
||||
Lutz thinks that looking at the status (and predefining a view values for it) may be sufficient and
|
||||
to have an additional parameter 'wanted_target' can be avoided.
|
||||
|
||||
|
||||
|
||||
28.11.2017
|
||||
++++++++++
|
||||
|
||||
Agenda Topic: discussion about the definition of pause/stop/start/shutdown
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
.. todo:: make an issue about the start/stop/pause/shutdown commands
|
||||
not all commands must always be implemented, but if they are implemented, they have a predefined meaning to it
|
||||
AND
|
||||
if somebody want to implement something with the predefined meaning, it must be with the predefined name
|
||||
|
||||
Agenda Topic: timestamps: mandatory or optional
|
||||
-----------------------------------------------
|
||||
|
||||
* providing timestamp is highly recommend, but stays optional
|
||||
* timestamps are (still) fractional unix time with a resolution of at least seconds
|
||||
* SEC-node implementor decides about implemented resolution
|
||||
|
||||
.. todo:: document this in an Issue
|
||||
|
||||
Agenda Topic: Interfaceclasses
|
||||
------------------------------
|
||||
|
||||
* discussion about custom vs. predefined parameters and properties
|
||||
* proposal to introduce 'features' in addition to base interface_class
|
||||
* features are listed by name in an additional module property called 'features'
|
||||
* explicit listing of 'features' seems better than guessing them from the existence of parameters
|
||||
* features have predefined 'dependencies', excludes, set of parameters with predefined meanings
|
||||
* Open question: how to figure out the difference of an unknown base class to a known base class?
|
||||
* Markus proposes to use just Features then.
|
||||
|
||||
|
||||
.. todo:: create an Issue for documenting this and for discussing it later in more detail
|
||||
|
||||
Agenda Topic: discussing existing Issues
|
||||
----------------------------------------
|
||||
|
||||
1) Issues: agreement to use Issues for documenting, closed
|
||||
2) Equipment_id is stored as a node property and is no longer part of the describing reply: agreement, closed
|
||||
3) already closed
|
||||
4) default timeout: change default to 10s, agreement, closed
|
||||
5) name change: live properties -> qualifiers to avoid misunderstands: agreement, closed
|
||||
6) keep alive: leave as to be discussed
|
||||
7) time synchronisation: leave to be discussed
|
||||
SEC-Nodes have its correct timestamp (provided by other means), have their own invented time, or no timestamps at all.
|
||||
agreement: the kind of SEC-node clock shall be noted as node property in the descriptive data. (this part closed)
|
||||
to be discussed: name of the node property (proposal: clock, datatype: Enum(None=0, relative=1, absolute=2)
|
||||
8) groups+hierarchy: leave as to discussed
|
||||
9) meaning/importance: leave as to be discussed
|
||||
10) Names and upper/lowercase: names can be uppercased as long as the lowercase version is still unique. agreement, close
|
||||
11) giving only module name for read/update/event request are extended with :value or :target: agreement on not specifying this.
|
||||
Clients are not allowed to use it, servers may support it but it is non-standard behaviour.
|
||||
|
||||
.. todo:: Issue 11 is still coded as second part of Issue 10 -> split it (Markus)
|
||||
|
||||
.. todo:: create an Issue about providing a mean to set the SEC-nodes clock from the ECS side.
|
||||
|
||||
.. note:: Klaus and Eddy leaving at this point
|
||||
|
||||
|
||||
Agenda Topic: Grouping/Hierachy (Issue 8)
|
||||
-----------------------------------------
|
||||
|
||||
* discussion about namespaces and use cases for groups
|
||||
* grouping is 'giving modules or parameters a name to allow guis to group them together'
|
||||
* the (lowercase) name of a (parameter)group is not allowed to clash with (lowercased) names of parameters of the same module
|
||||
* the (lowercase) name of a (module)group is not allowed to clash with (lowercased) names of modules of the same node
|
||||
* agreement, closing this issue
|
||||
|
||||
|
||||
.. todo:: create an Issue for PID tables
|
||||
|
||||
|
||||
Topic: handling of driver generated timestamps in the HZB-DLL
|
||||
-------------------------------------------------------------
|
||||
|
||||
1) initiate the timestamp with NAN before calling the HW-read_a_value callback, which may provide an timestamp
|
||||
2) if configured to do so, a NAN timestamp is replaced after the callback with the current time
|
||||
3) if the timestamp is still NAN (or not expressable by digits), it is NOT send
|
||||
|
||||
.. todo:: @Frank: document this !
|
||||
|
||||
|
||||
Discussion about activate/deactivate
|
||||
------------------------------------
|
||||
|
||||
* normally values for all values are send before the activated reply is sent
|
||||
* there are very rare cases where a value can (not yet) be determined. In this case it is acceptable to send a null value.
|
||||
* a null value is also accepted when setting parameters of a complex datatype and not all members shall be updated.
|
||||
|
||||
.. todo:: create an issue about the usage of null
|
||||
|
||||
.. note:: tour around PSI
|
||||
|
||||
.. note:: presentation of the SEA and SICS concept by Markus Zolliker
|
||||
|
||||
.. note:: detailed showcase of the HZB-DLL source
|
||||
|
||||
.. note:: we need more use cases and sequencediagrams
|
||||
|
||||
|
||||
29.11.2017
|
||||
++++++++++
|
||||
|
||||
* detailed presentation of the playground
|
||||
* discussion about implementation details
|
||||
* structure of config files
|
||||
* introduction to writing secop modules + how to configure them
|
||||
* live demo
|
||||
|
||||
* fixing the amagnet
|
||||
* discussing error propagation (bugs in hw-driver)
|
||||
|
||||
.. note:: meeting was closed around 14:30
|
@ -1,232 +0,0 @@
|
||||
SECoP Messages
|
||||
==============
|
||||
|
||||
All Messages are formatted in the same way:
|
||||
<keyword>[<space><specifier>[<space><JSON_formatted_data>]]<linefeed>
|
||||
|
||||
where [] enclose optional parts. This basically results in 3 different possible
|
||||
formattings:
|
||||
|
||||
* type A: "keyword\\n"
|
||||
* type B: "keyword specifier\\n"
|
||||
* type C: "keyword specifier JSON_data\\n"
|
||||
|
||||
Note: numerical values and strings appear 'naturally' formatted in JSON, i.e. 5.0 or "a string"
|
||||
|
||||
<keyword> is one of a fixed list of defined keywords, <specifier> is either the
|
||||
name of the module optionally followed by ':' + the name of a command or parameter,
|
||||
or one of a fixed list of predefined keywords, depending on the message keyword.
|
||||
|
||||
At the moment it is considered syntactic sugar to omit the parametername in a request.
|
||||
In replies the SEC-node (in the playground) will always use the correct parameter.
|
||||
On change-requests the parameter is assumed to be 'target', on trigger-requests it is
|
||||
assumed to be 'value'. Clients should not rely on this and explicitly state the parametername!
|
||||
|
||||
All names and keywords are defined to be identifiers in the sense, that they are not longer
|
||||
than 63 characters and consist only of letters, digits and underscore and do not start
|
||||
with a digit. (i.e. T_9 is ok, whereas t{9} is not!)
|
||||
No rule is without exception, there is exactly ONE special case: the identify request
|
||||
consists of the literal string '\*IDN?\\n' and its answer is formatted like an valid SCPI
|
||||
response for \*IDN?.
|
||||
|
||||
We rely on the underlying transport to not split messages, i.e. all messages are
|
||||
transported as a whole and no message interrupts another.
|
||||
|
||||
Also: each client MUST at any time correctly handle incoming event messages, even
|
||||
if it didn't activate them!
|
||||
|
||||
Implementation node:
|
||||
Both SEC-node and ECS-client can close the connection at any time!
|
||||
|
||||
|
||||
List of Intents/Actions:
|
||||
------------------------
|
||||
|
||||
* Identify -> Ident
|
||||
* Describe -> Description
|
||||
* Activate Events -> initial data transfer -> end-of-transfer-marker
|
||||
* Deactivate Async Events -> confirmation
|
||||
* Command <module>:<command> -> confirmation -> result_event
|
||||
* Heartbeat <nonce> -> Heartbeat_reply
|
||||
* Change <module>[:<param>] JSON_VALUE -> confirmation -> readback_event
|
||||
* TRIGGER <module>[:<param>] -> read_event
|
||||
|
||||
At any time an Event may be replied. Each request may also trigger an Error.
|
||||
|
||||
Line-ending is \lf.
|
||||
\cr is ignored and never send.
|
||||
Warning: One Message per line: Description line can be looooong!!!
|
||||
|
||||
|
||||
Allowed combinations as examples:
|
||||
(replace <..> with sensible stuff)
|
||||
|
||||
|
||||
Identify
|
||||
--------
|
||||
|
||||
* Request: type A: '\*IDN?'
|
||||
* Reply: special: 'SECoP, SECoPTCP, V2016-11-30, rc1'
|
||||
* queries if SECoP protocol is supported and which version it is
|
||||
|
||||
The format is intentionally choosen to be compatible to SCPI (for this query only).
|
||||
It is NOT intended to transport information about the manufacturer of the hardware, but to identify this as a SECoP device and transfer the protocol version!
|
||||
|
||||
|
||||
Describe
|
||||
--------
|
||||
|
||||
* Request: type A: 'describe'
|
||||
* Reply: type C: 'describing <ID> {"modules":{"T1":{"baseclass":"Readable", ....'
|
||||
* request the 'descriptive data'. The format needs to be better defined and
|
||||
may possibly just follow the reference implementation.
|
||||
|
||||
<ID> identifies the equipment. It should be unique. Our suggestion is to use something along <facility>_<id>, i.e. MLZ_ccr12 or PSI_oven4.
|
||||
|
||||
|
||||
Activate Async Events
|
||||
---------------------
|
||||
|
||||
* Request: type A: 'activate'
|
||||
* Reply: several EVENT lines (initial value transfer) followed by: type A: 'active'
|
||||
* Activates sending of Async Events after transferring all live quantities once
|
||||
and an 'end-of-initial-transfer' marker. After this events are enabled.
|
||||
|
||||
|
||||
Deactivate Async Events
|
||||
-----------------------
|
||||
|
||||
* Request: type A: 'deactivate'
|
||||
* Reply: type A: 'inactive'
|
||||
* Deactivate sending of async Events. A few events may still be on their way until the 'inactive' message arrives.
|
||||
|
||||
|
||||
Execute Command
|
||||
---------------
|
||||
|
||||
* Request: type B: 'do <module>:<command>' for commands without arguments
|
||||
* Request: type C: 'do <module>:<command> JSON_argument' for commands with arguments
|
||||
* Reply: type C: 'done <module>:<command> JSON_result' after the command finished
|
||||
* start executing a command. When it is finished, the reply is send.
|
||||
The JSON_result is the a list of all return values (if any), appended with qualifiers (timestamp)
|
||||
|
||||
|
||||
Write
|
||||
-----
|
||||
|
||||
* Request: type C: 'change <module>[:<param>] JSON_value'
|
||||
* Reply: type C: 'changed <module>:<param> JSON_read_back_value'
|
||||
* initiate setting a new value for the module or a parameter of it.
|
||||
|
||||
Once this is done, the read_back value is confirmed by the reply.
|
||||
|
||||
|
||||
Trigger
|
||||
-------
|
||||
|
||||
* Request: type B: 'read <module>[:<param>]'
|
||||
* Reply: None directly. However, one Event with the read value will be send.
|
||||
* Read the requested quantity and sends it as an event (even if events are disabled or the value is not different to the last value).
|
||||
|
||||
|
||||
Heartbeat
|
||||
---------
|
||||
|
||||
* Request: type A: 'ping'
|
||||
* Request: type B: 'ping <nonce>'
|
||||
* Reply: type A: 'pong'
|
||||
* Reply: type B: 'pong <nonce>'
|
||||
* Replies the given argument to check the round-trip-time or to confirm that the connection is still working.
|
||||
|
||||
<nonce> may not contain <space>. It is suggested to limit to a string of up to 63 chars consisting of letters, digits and underscore not beginning with a digit. If <nonce> is not given (Type A), reply without it.
|
||||
|
||||
|
||||
EVENT
|
||||
-----
|
||||
|
||||
Events can be emitted any time from the SEC-node (except if they would interrupt another message).
|
||||
|
||||
* Request: None. Events can be requested by Trigger or by Activating Async Mode.
|
||||
* Reply: type C: 'event <module>:<param> JSON_VALUE'
|
||||
* Informs the client that a parameter got changed its value.
|
||||
|
||||
In any case the JSON_value contain the available qualifiers as well:
|
||||
* "t" for the timestamp of the event.
|
||||
* "e" for the error of the value.
|
||||
* "u" for the unit of the value, if deviating from the descriptive data
|
||||
* further qualifiers, if needed, may be specified.
|
||||
|
||||
The qualifiers are a dictionary at position 2 of a list, where the value occupies position 1.
|
||||
This holds true also for complex datatypes (of value)!
|
||||
|
||||
examples:
|
||||
|
||||
* 'update T1:value [3.479, {"t":"149128925.914882", "e":0.01924}]
|
||||
* 'update T1:p [12, {"t":"149128927.193725"}]'
|
||||
* 'update Vector:value [[0.01, 12.49, 3.92], {"t":"149128925.914882"}]'
|
||||
|
||||
|
||||
ERROR
|
||||
-----
|
||||
|
||||
* Request: None. can only be a reply if some request fails.
|
||||
* Reply: type C: 'ERROR <errorclass> JSON_additional_stuff'
|
||||
* Following <errorclass> are defined so far:
|
||||
- NoSuchDevice: The action can not be performed as the specified device is non-existent.
|
||||
- NoSuchParameter: The action can not be performed as the specified parameter is non-existent.
|
||||
- NoSuchCommand: The specified command does not exist.
|
||||
- CommandFailed: The command failed to execute.
|
||||
- CommandRunning: The command is already executing.
|
||||
- ReadOnly: The requested write can not be performed on a readonly value..
|
||||
- BadValue: The requested write or Command can not be performed as the value is malformed or of wrong type.
|
||||
- CommunicationFailed: Some communication (with hardware controlled by this SEC-Node) failed.
|
||||
- IsBusy: The reequested write can not be performed while the Module is Busy
|
||||
- IsError: The requested action can not be performed while the module is in error state.
|
||||
- Disabled: The requested action can not be performed at the moment. (Interlocks?)
|
||||
- SyntaxError: A malformed Request was send
|
||||
- InternalError: Something that should never happen just happened.
|
||||
|
||||
The JSON part should reference the offending request and give an explanatory string.
|
||||
|
||||
examples:
|
||||
|
||||
* 'ERROR Disabled ["change", "V15", "on", "Air pressure too low to actuate the valve.", {"exception":"RuntimeException","file":"devices/blub/valve.py", "line":13127, "frames":[...]}]'
|
||||
* 'ERROR NoSuchDevice ["read","v19", "v19 is not configured on this SEC-node"]'
|
||||
* 'ERROR SyntaxError "meas:Volt?"
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
(client connects):
|
||||
(client) '\*IDN?'
|
||||
(SEC-node) 'Sine2020WP7.1&ISSE, SECoP, V2016-11-30, rc1'
|
||||
(client) 'describe'
|
||||
(SEC-node) 'describing SECoP_Testing {"modules":{"T1":{"baseclass":"Readable", ...
|
||||
(client) 'activate'
|
||||
(SEC-node) 'update T1 [3.45,{"t":"149128925.914882","e":0.01924}]'
|
||||
...
|
||||
(SEC-node) 'active'
|
||||
(SEC-node) 'update T1 [3.46,{"t":"149128935.914882","e":0.01912}]'
|
||||
(client) 'ping fancy_nonce_37'
|
||||
(SEC-node) 'pong fancy_nonce_37'
|
||||
(SEC-node) 'update T1 [3.49,{"t":"149128945.921397","e":0.01897}]'
|
||||
...
|
||||
|
||||
merge datatype and validator:
|
||||
-----------------------------
|
||||
* enum, int, double, bool, tuple, struct as before
|
||||
* ["blob", <maximum_size_in_bytes>] or ["blob", <maximum_size_in_bytes>, <minimum_size_in_bytes>]
|
||||
* ["string", <maximum_allowed_length>] or ["string", <max_size_in_bytes>, <minimum_size_in_bytes>]
|
||||
* ["array", <basic_data_type>, <max_elements>] or ["array", <dtype>, <max_elements>, <min_elements>]
|
||||
|
||||
interface_class
|
||||
---------------
|
||||
* Drivable, Writable, Readable, Module (first character uppercase, no middle 'e')
|
||||
|
||||
transfer_of_blob
|
||||
----------------
|
||||
* transport-encoding as base64-encoded string (no prefixed number of bytes....)
|
||||
|
@ -1,8 +0,0 @@
|
||||
Activate subset of modules
|
||||
==========================
|
||||
|
||||
* activate/deactivate may get an optional 2nd argument and work only on this.
|
||||
* add equipment_id [_0-9a-zA-A]{4,} as SEC-node property (mandatory) (prefixed with ficility/manufacturer)
|
||||
* change response to 'describe' to 'describing ALL <json_description>'
|
||||
* '(de-)activate samething' -> '(de-)activated something'
|
||||
|
@ -1,18 +0,0 @@
|
||||
Motivation
|
||||
==========
|
||||
|
||||
* SECoP motivation proposal
|
||||
* simple, inclusive and self describing
|
||||
* write drivers only once
|
||||
* different institutes wrote their own driver collection which fulfils all their needs and it works reliable
|
||||
* as secondary effect the standard drivers still can be used so their are well tested and may become more reliable
|
||||
|
||||
SECoP
|
||||
-----
|
||||
|
||||
The SECoP (Sample Environment Communication Protocol) is an Inclusive, Simple and Self Explaining (ISSE) communication protocol.
|
||||
Inclusive means, that facilities can use this protocol and don't have to change their work flow (rewrite drivers completely or organize and handle hardware in a specific way to fulfil SECoP requirements).
|
||||
Simple means it should be easy to integrate and to use.
|
||||
Self Explaining means that with SECoP, not only the pure data is transported. It also transports meta data, which allows environment control software to configure by itself.
|
||||
The benefit of SECoP will be to circulate expensive devices between different facilities with minimised effort for configuration and integration.
|
||||
This should result in an increased utilisation of expensive equipment.
|
@ -1,42 +0,0 @@
|
||||
Notes
|
||||
=====
|
||||
|
||||
No installation required or recommended
|
||||
---------------------------------------
|
||||
|
||||
everything runs directly from the checkout.
|
||||
|
||||
you need:
|
||||
- python2.7.*
|
||||
- pip
|
||||
- linux OS (Mac may work as well)
|
||||
|
||||
install requirements with pip:
|
||||
$ sudo pip install -r requirements.txt
|
||||
|
||||
to execute a program, prefix its name with bin/, e.g.:
|
||||
$ bin/make_doc.py
|
||||
$ bin/server.py start test
|
||||
|
||||
a testsuite is planned but nothing is there yet.
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
||||
* bin contains the executables (make_doc.py, server.py)
|
||||
* doc is the root node of the docu (see index.md)
|
||||
* etc contains the configurations for the server(s) and devices
|
||||
* html contains the docu after make_doc.py was run
|
||||
* log contains some (hopefully) log output from the servers
|
||||
* pid contains pidfiles if a server is running
|
||||
* src contains the python source
|
||||
|
||||
* src/client: client specific stuff (proxy)
|
||||
* src/devices: devices to be used by the server (and exported via SECoP)
|
||||
* src/lib: helper stuff (startup, pidfiles, etc)
|
||||
* src/protocol: protocol specific stuff
|
||||
* src/errors.py: internal errors
|
||||
* src/server.py: device-managing part of the server (transport is in src/protocol/transport)
|
||||
* src/validators.py: validators used by the devices. may be moved to src/protocol
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
Outdated documentation
|
||||
======================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 0
|
||||
|
||||
messages
|
||||
descprop
|
||||
hierarchy
|
||||
descjson
|
||||
timeformat
|
||||
modsubset
|
||||
heartbeat
|
||||
jsonstruct
|
||||
datatypes
|
||||
commands
|
||||
todo
|
||||
notes
|
||||
|
||||
|
@ -1,924 +0,0 @@
|
||||
SECoP: Sample Environment Communication Protocol
|
||||
################################################
|
||||
|
||||
V2017-09-14
|
||||
|
||||
Goal
|
||||
====
|
||||
|
||||
The main goal of the "committee for the standardization of sample
|
||||
environment communication" is to establish a common standard protocol
|
||||
SECoP for interfacing sample environment equipment to experiment control
|
||||
software.
|
||||
|
||||
Definition: Experiment Control Software ECS
|
||||
Software controlling the hardware for carrying out an experiment. Includes the user
|
||||
interface. Usually speaks several protocols with different parts of the instrument.
|
||||
Often also called instrument control.
|
||||
|
||||
There is a task (7.1) within the European framework SINE2020 also
|
||||
dealing with this subject. In its description we read:
|
||||
|
||||
... The standard should be defined in a way that it is compatible
|
||||
with a broad variety of soft- and hardware operated at the different
|
||||
large scale facilities. … The adoption of this standard will greatly
|
||||
facilitate the installation of new equipment and the share of
|
||||
equipment between the facilities. ...
|
||||
|
||||
This does also cover the aims of the committee.
|
||||
|
||||
The idea is, that a sample environment apparatus can easily be moved
|
||||
between facilities and instruments/beamlines. As long as the facilities
|
||||
have implemented a SECoP client within its ECS, and on the apparatus a
|
||||
SECoP server is implemented as the SEC node, using the apparatus for an
|
||||
experiment should be straightforward. An ECS can be built in a way, that
|
||||
the configuration of a SEC node may be as short as entering a network
|
||||
address, as the description can be loaded over the protocol (in
|
||||
addition, the electronic communication link, electricity and may be
|
||||
cooling water or pressurized air etc. have to be connected, but that is
|
||||
out of scope …)
|
||||
|
||||
Definition: Sample Environment Control Node (SEC node)
|
||||
Computing unit or process or task, connected to all control units (temperature controller, flow controller, pressure sensor ...) of a sample environment, bridge to the ECS. SECoP specifies how ECS speaks with the SEC node.
|
||||
The SEC node allows the ECS to access a set of modules (and their parameters) via the SECoP. It also provides a list of accessible modules and parameters.
|
||||
|
||||
Other requirements
|
||||
------------------
|
||||
|
||||
- the protocol should be easy to use
|
||||
|
||||
- it should be easy to implement in connection with existing ECSs and
|
||||
sample environment control software
|
||||
|
||||
- it should be possible to be implemented on the most common platforms
|
||||
(operating systems and programming languages)
|
||||
|
||||
- the protocol should be defined in way that allows a maximum
|
||||
**compatibility**: Newer and older versions of the syntax should
|
||||
be compatible
|
||||
|
||||
- the protocol should be defined in a way, which allows a maximum
|
||||
**flexibility**: A simple (= with minimal features) ECS
|
||||
implementation should be able to communicate with a complex SEC
|
||||
node (with a lot of features), and an ECS with a rich number of
|
||||
features should be able to cope with a simple SEC node,
|
||||
implementing only a minimum number of features
|
||||
|
||||
Hardware Abstraction
|
||||
====================
|
||||
|
||||
Modules
|
||||
-------
|
||||
|
||||
Definition: Module
|
||||
One logical component of an abstract view of the sample environment. Can at least be read.
|
||||
May be ’driven' (set new setpoint). May have parameters influencing how it achieves
|
||||
its function (e.g. PID parameters). May have some additional diagnostics (read-only) parameters.
|
||||
May provide some additional status information (temperature stable?, setpoint reached?)
|
||||
Reading a module returns the result of the corresponding physical measurement.
|
||||
|
||||
In earlier discussion we used the term "device" for module, which might
|
||||
be misleading, as "device" is often used for an entire apparatus, like a
|
||||
cryomagnet or humidity cell. In the context of SECoP, an apparatus in
|
||||
general is composed of several modules. For example different
|
||||
temperature sensors in one apparatus can be seen as different modules.
|
||||
|
||||
An SEC node controls several (or one or no) modules. Modules also have
|
||||
some descriptive data (name, type, list\_of\_parameters,
|
||||
list-of\_commands,...).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
A module has several parameters associated with it. A parameter is
|
||||
addressed by the combination of module and parameter name. Module names
|
||||
have to be unique within an SEC node, parameter names have to be unique
|
||||
within a module.
|
||||
|
||||
Module and parameter names should be in english (incl. acronyms), using
|
||||
only ascii letters and some additional characters (see section "Message
|
||||
Syntax"). A maximum name length might be imposed.
|
||||
|
||||
Definition: Parameter
|
||||
The main parameter of a module is its value. Writable parameters may influence the
|
||||
measurement (like PIDs). Additional parameters may give more information about its
|
||||
state (running, target reached), or details about its functioning (heater power) for
|
||||
diagnostics purposes. Parameters with a predefined meaning are listed in the standard,
|
||||
they must always be used in the same way. Custom parameters are defined by the
|
||||
implementation of the SEC node, the ECS can use them only in a general way, as their
|
||||
meaning is not known.
|
||||
|
||||
|
||||
The following parameters are predefined (extensible):
|
||||
|
||||
- **value**
|
||||
|
||||
- **status** (consists of two elements: a status with predefined values
|
||||
as "idle","busy","error", and a describing text).
|
||||
*Remark: it is proposed to add additional states (starting,
|
||||
started, pausing, paused, stopping, warning). It has to be
|
||||
discussed, if this (and therefore a start and pause command)
|
||||
makes sense. Generally we want to keep the number of states as
|
||||
small as possible here.*
|
||||
|
||||
- **target** (not present, if the module is not writable)
|
||||
|
||||
- **pollinterval** (double, a hint for the module for the polling interval in seconds)
|
||||
|
||||
The following parameters were discussed at the meeting in
|
||||
|
||||
- **ramp** (writable parameter, desired ramp. Units: main units/min)
|
||||
|
||||
- **use\_ramp** (writable, 1 means: use given ramp, 0 means: go as fast as possible)
|
||||
|
||||
- **setpoint** (ramping setpoint, read only)
|
||||
|
||||
- **time\_to\_target** (read only, expected time to reach target)
|
||||
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
A module may also have commands associated with it. A command is
|
||||
addressed by the combination of module and parameter name. Like
|
||||
parameters, command names have to be unique within a module, and should
|
||||
be in english (incl. acronyms), using only ascii letters and some
|
||||
additional characters (see section "Message Syntax"). A maximum name
|
||||
length might be imposed.
|
||||
|
||||
Definition: Command
|
||||
Commands are provided to initiate specified actions of the module.
|
||||
They should return immediately after that action is initiated, i.e.
|
||||
should not wait until some other state is reached. Commands may get
|
||||
an argument list and may return a result list.
|
||||
Commands with a predefined meaning are listed in the standard,
|
||||
they must always be used in the same way.
|
||||
|
||||
Custom commands are defined by the implementation of the SEC node, the
|
||||
ECS can use them only in a general way, as their meaning is not known.
|
||||
|
||||
So far the only command defined (for driveable modules) is ‘stop’ (no
|
||||
arguments, no result). When a modules target is changed, it is 'driving'
|
||||
to a new value until the target is reached or until its stop command
|
||||
is sent.
|
||||
It is still to be discussed, what this exactly means for temperature
|
||||
devices (heater off vs. ‘stay at current temp’).
|
||||
|
||||
The following commands are predefined (extensible):
|
||||
|
||||
- stop (stop a running action)
|
||||
|
||||
proposed further commands:
|
||||
|
||||
- start, pause (proposed from ILL)
|
||||
|
||||
- shutdown (go to safe state)
|
||||
|
||||
|
||||
Properties
|
||||
----------
|
||||
|
||||
*definition of properties to be rewitten, see* `SECoP issue 5`_
|
||||
|
||||
Definition: Properties
|
||||
Parameters have a value, live properties and descriptive properties. All properties have a predefined name and meaning.
|
||||
|
||||
Live Properties
|
||||
Properties which change their value during an experiment.
|
||||
|
||||
Descriptive Properties
|
||||
Properties that do not change during an experiment. They describe the usage of the parameter.
|
||||
|
||||
|
||||
Live Properties (or *qualifiers* ?) are optional.
|
||||
|
||||
There are currently only 2 live properties:
|
||||
|
||||
- timestamp (named ‘t’ in the proposed syntax). The time when the
|
||||
parameter has changed or was verified/measured (when no timestamp
|
||||
is given, the ECS should use the time of the update message as
|
||||
the timestamp)
|
||||
|
||||
- sigma (named ‘e’ in the proposed syntax). The uncertainty of a
|
||||
measurement (default: unspecified)
|
||||
|
||||
other live properties might be added later to the standard.
|
||||
|
||||
For a list of descriptive properties see chapter "Descriptive Data".
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
The idea is, that the ECS can determine the functionality of a module
|
||||
from its class.
|
||||
|
||||
Base classes (recommended):
|
||||
|
||||
- Readable
|
||||
|
||||
- Writable (must have a target parameter)
|
||||
|
||||
- Drivable (a Writable, must have a stop command, the status parameter will indicate
|
||||
busy for a longer-lasting operation)
|
||||
|
||||
Examples of classes:
|
||||
|
||||
- CryomagnetSupply (a Drivable, with ramp and optional a persistent
|
||||
switch)
|
||||
|
||||
- TemperatureLoop (a Drivable, with PIDs, optional with ramp)
|
||||
|
||||
The standard contains a list of classes, and a specification of the
|
||||
functionality for each of them. The list might be extended over time.
|
||||
Already specified base classes may be extended in later releases of the
|
||||
specification, but earlier definitions will stay intact, i.e. no
|
||||
removals or redefinitions will occur.
|
||||
|
||||
The module class is in fact a list of classes (highest level class
|
||||
first). The ECS chooses the first class from the list which is known to
|
||||
it.
|
||||
|
||||
Protocol
|
||||
========
|
||||
|
||||
The basic element of the protocol are messages.
|
||||
|
||||
Message Syntax
|
||||
--------------
|
||||
|
||||
A message is one line of text, coded in ASCII (may be extended to UTF-8
|
||||
later if needed).
|
||||
|
||||
A message ends with a line feed character (ASCII 10), it may be preceded
|
||||
by a carriage return character (ASCII 13), which must be ignored. A
|
||||
message starts with a keyword, followed optionally by one space and a qualified name
|
||||
or another item not containing spaces, followed optionally by one space and a JSON
|
||||
formatted value. Note: numerical values and strings appear 'naturally' formatted
|
||||
in JSON, i.e. 5.0 or "a string".
|
||||
|
||||
A qualified name consists of a module identifier, a colon as separator
|
||||
and a parameter or command identifier. The identifiers are composed by
|
||||
lowercase ascii letters, digits and underscore, where a digit may not
|
||||
appear as the first character. Identifiers starting with underscore are
|
||||
reserved for special purposes like internal use for debugging. The
|
||||
identifier length is limited (<=63 characters).
|
||||
|
||||
A SEC node might implement custom messages for debugging purposes, which are not
|
||||
part of the standard. Custom messages start with an underscore or might just be
|
||||
an empty line. The latter might be used as a request for a help text, when logged
|
||||
in from a command line client like telnet or netcat. Messages not starting with
|
||||
an underscore and not defined in the following list are reserved for future extensions.
|
||||
|
||||
Message Summary
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 20 60
|
||||
:header-rows: 1
|
||||
|
||||
* - message
|
||||
- message kind
|
||||
- syntax
|
||||
|
||||
* - identification
|
||||
- request
|
||||
- **\*IDN?**
|
||||
|
||||
* -
|
||||
- reply
|
||||
- ISSE&SINE2020\ **,SECoP,**\ *version,add.info*
|
||||
|
||||
* - description
|
||||
- request
|
||||
- **describe**
|
||||
|
||||
* -
|
||||
- reply
|
||||
- **describing ALL** *description*
|
||||
|
||||
* - activate updates
|
||||
- request
|
||||
- **activate** *[module]*
|
||||
|
||||
* -
|
||||
- reply (after first updates)
|
||||
- **active** *[module]*
|
||||
|
||||
* - update
|
||||
-
|
||||
-
|
||||
|
||||
* -
|
||||
- asynchronous msg.
|
||||
- **update** *module*\ **:**\ *parameter value*
|
||||
|
||||
* - deactivate updates
|
||||
- request
|
||||
- **deactivate** *[module]*
|
||||
|
||||
* -
|
||||
- reply
|
||||
- **inactive** *[module]*
|
||||
|
||||
* - change value
|
||||
- request
|
||||
- **change** *module*\ **:**\ *parameter value*
|
||||
|
||||
* -
|
||||
- reply
|
||||
- **changed** *module*\ **:**\ *parameter value*
|
||||
|
||||
* - read request
|
||||
- request
|
||||
- **read** *module*\ **:**\ *parameter*
|
||||
|
||||
* -
|
||||
- reply
|
||||
- **update** *module*\ **:**\ *parameter value*
|
||||
|
||||
* - execute command
|
||||
- request
|
||||
- **do** *module*\ **:**\ *command [argument]*
|
||||
|
||||
* -
|
||||
- reply
|
||||
- **done** *module*\ **:**\ *command [result]*
|
||||
|
||||
* - error
|
||||
-
|
||||
-
|
||||
|
||||
* -
|
||||
- reply (on any message)
|
||||
- **error** *errortype* *info*
|
||||
|
||||
* - heartbeat
|
||||
- request
|
||||
- **ping** *[id]*
|
||||
|
||||
* -
|
||||
- reply
|
||||
- **pong** *[id]* [\ **{"t":** *localtime* **}**\ ]
|
||||
|
||||
Identification
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The syntax of the identification message differs a little bit from other
|
||||
messages, as it should be compatible with IEEE 488.2. The identification
|
||||
request "\ **\*IDN?**\ " is meant to be sent as the first message after
|
||||
establishing a connection. The reply consists of 4 comma separated
|
||||
fields, where the second and third field determine the used protocol.
|
||||
|
||||
In this and in the following examples, messages sent to the server are marked with "> ",
|
||||
and messages sent to the client are marked with "< "
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> *IDN?
|
||||
< ISSE&SINE2020,SECoP,V2017-05-30,rc1
|
||||
|
||||
Description
|
||||
~~~~~~~~~~~
|
||||
|
||||
The next messages normally exchanged are the description request and
|
||||
reply. The reply is a structured JSON value describing the name of
|
||||
modules exported and their parameters, together with the corresponding
|
||||
properties.
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> describe
|
||||
< describing PSI\_MP03 {"modules":["t1",["class":[ "temperature\_sensor","readable"],"parameters":["value", ...
|
||||
|
||||
It is not yet clear what the second item in the reply message should be.
|
||||
In this example it is the equipment ID, but this is redundant, as
|
||||
"equipment_id" is also a SEC node property.
|
||||
See `SECoP Issue 2`_ (Equipment ID in Describing Message)
|
||||
|
||||
Remark:
|
||||
this reply might be a very long line, no line breaks are allowed in the
|
||||
JSON value.
|
||||
|
||||
Activate Updates
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The parameterless "activate" request triggers the SEC node to send the
|
||||
values of all its modules and parameters as update messages. When this
|
||||
is finished, the SEC node must send an "active" reply.
|
||||
|
||||
A SEC node might accept a module name as second item of the
|
||||
message, activating only updates on the parameters of the module.
|
||||
In this case, the "active" reply also contains the module names.
|
||||
|
||||
A SEC Node not implementing module-wise activation must not sent the module
|
||||
name in its reply, and must activate all modules.
|
||||
|
||||
Update
|
||||
~~~~~~
|
||||
|
||||
When activated, update messages are delivered without explicit request
|
||||
from the client. The value is a JSON array with the value as its first
|
||||
element, and an JSON object containing the qualifiers (live properties)
|
||||
as its second element:
|
||||
|
||||
"t": the timestamp (recommended, when the system has a synchronized
|
||||
time, the format is fractional seconds since 1970-01-01T00:00:00+00:00)
|
||||
|
||||
See also `SECoP Issue 3`_ (Timestamps)
|
||||
|
||||
"e": the error of the quantity (optional)
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> activate
|
||||
< update t1:value [295.13,{"t":1505396348.188388,"e":0.01}]
|
||||
< update t1:status [[400,"heater broken or disconnected"],{"t":1505396348.288388}]
|
||||
< active
|
||||
|
||||
Deactivate Updates
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A parameterless message. After the "inactive" reply no more updates are
|
||||
delivered if not triggered by a read message.
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> deactivate
|
||||
< update t1:value [295.13,{"t":1505396348.188388}]
|
||||
< inactive
|
||||
|
||||
remark: the update message in the second line was sent before the deactivate message
|
||||
was treated. After the "inactive" message, the client can expect that no more untriggered
|
||||
update message are sent.
|
||||
|
||||
The deactivate message might optionally accept a module name as second item
|
||||
of the message for module-wise deactivation. If module-wise deactivation is not
|
||||
supported, it should ignore a deactivate message which contains a module name.
|
||||
|
||||
Remark: it is not clear, if module-wise deactivation is really useful. A SEC Node
|
||||
supporting module-wise activation does not necessarily need to support module-wise
|
||||
deactivation.
|
||||
|
||||
Change Value
|
||||
~~~~~~~~~~~~
|
||||
|
||||
the change value message contains the name of the module or parameter
|
||||
and the value to be set. The value is JSON formatted, but note that for
|
||||
a floating point value this is a simple decimal coded ASCII number. As
|
||||
soon as the set-value is read back from the hardware, a "changed"
|
||||
message is sent (in case updates are activated). If the value is not
|
||||
stored in hardware, the "changed" message can be sent immediately.
|
||||
|
||||
Example on a connection with activated updates. Live properties are replaced by {...} for brevity here.
|
||||
|
||||
.. code::
|
||||
|
||||
> read mf:status
|
||||
< update mf:status [[100,"OK"],{...}]
|
||||
< change mf:target 12
|
||||
< update mf:status [[300,"ramping field"],{...}]
|
||||
< changed mf:target [12,{...}]
|
||||
|
||||
The status changes from "idle" to "busy". The ECS will be informed with a further update message on mf:status, when the module has finished ramping.
|
||||
|
||||
Read Request
|
||||
~~~~~~~~~~~~
|
||||
|
||||
With the read request message the ECS may ask the SEC node to update a
|
||||
value as soon as possible, without waiting for the next regular update.
|
||||
The reply is an update message. If updates are not activated, the
|
||||
message can be treated like a read message in a request-reply scheme as
|
||||
in the previous SECoP proposal.
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> read t1:value
|
||||
< update t1:value [295.13,{"t":1505396348.188}]
|
||||
> read t1:status
|
||||
> update t1:status [[100,"OK"],{"t":1505396348.548}]
|
||||
|
||||
Command
|
||||
~~~~~~~
|
||||
|
||||
A command may have arguments. Multiple arguments can be given as a JSON list.
|
||||
A command may also have a return value. The "done" reply always contains the
|
||||
JSON part with at least the timestamp, if supported. If no value is returned,
|
||||
the data part is set to "null".
|
||||
The "done" message should be returned quickly, the time scale should be in the
|
||||
order of the time needed for communications. Actions which have to wait for physical
|
||||
changes, can be triggered with a command. The information about the success of
|
||||
such an action has to be transferred via parameters, namely the status parameter.
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> do t1:stop
|
||||
< done t1:stop [null, {"t": 1505396348.876}]
|
||||
|
||||
Error Reply
|
||||
~~~~~~~~~~~
|
||||
|
||||
Contains an error class from the list below as its second item.
|
||||
The third item of the message is a JSON list,
|
||||
containing the related request message as its first element, a human readable text
|
||||
as its second element. The third element is a JSON-Object, containing possibly
|
||||
implementation specific information about the error (stack dump etc.).
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> read tx:target
|
||||
< error NoSuchModule ["read tx:target", "tx is not configured on this SEC node", {}]
|
||||
> read ts:target
|
||||
< error NoSuchParameter ["read ts:target", "ts has no parameter target", {}]
|
||||
> meas:volt?
|
||||
< error SyntaxError ["meas:volt?", "unknown keyword", {}]
|
||||
|
||||
Error Classes
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
|
||||
* - NoSuchModule
|
||||
- The action can not be performed as the specified module is non-existent.
|
||||
|
||||
* - NoSuchParameter
|
||||
- The action can not be performed as the specified parameter is non-existent.
|
||||
|
||||
* - NoSuchCommand
|
||||
- The specified command does not exist.
|
||||
|
||||
* - CommandFailed
|
||||
- The command failed to execute.
|
||||
|
||||
* - CommandRunning
|
||||
- The command is already executing.
|
||||
|
||||
* - ReadOnly
|
||||
- The requested write can not be performed on a readonly value..
|
||||
|
||||
* - BadValue
|
||||
- The requested write or Command can not be performed as the value is malformed or of wrong type.
|
||||
|
||||
* - CommunicationFailed
|
||||
- Some communication (with hardware controlled by this SEC-Node) failed.
|
||||
|
||||
* - IsBusy
|
||||
- The reequested write can not be performed while the Module is Busy
|
||||
|
||||
* - IsError
|
||||
- The requested action can not be performed while the module is in error state.
|
||||
|
||||
* - Disabled
|
||||
- The requested action can not be performed at the moment. (Interlocks?)
|
||||
|
||||
* - SyntaxError
|
||||
- A malformed Request was send
|
||||
|
||||
* - InternalError
|
||||
- Something that should never happen just happened.
|
||||
|
||||
|
||||
Timeout Issues / Heartbeat
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In order to detect that the other end of the communication is not dead,
|
||||
a heartbeat may be sent. The second part of the message (the id) may
|
||||
not contain a space and should be short. It may be omitted. The reply
|
||||
will contain exactly the same id.
|
||||
|
||||
A SEC node might also decide to close a connection when it gets no
|
||||
messages for a certain time. The mechanism is under discussion.
|
||||
|
||||
Generally speaking: both
|
||||
ECS and SEC side needs to be aware that the other side may close the
|
||||
connection at any time!
|
||||
|
||||
Example:
|
||||
|
||||
.. code::
|
||||
|
||||
> ping 123
|
||||
< pong 123 {"t": 1505396348.543}
|
||||
|
||||
The "pong" message has an additional function: it sends back the time
|
||||
on the server, if it supports timestamps. This can be used to
|
||||
synchronize the time.
|
||||
|
||||
See also `SECoP Issue 4`_ (Timeout), `SECoP Issue 6`_ (Keep Alive),
|
||||
`SECoP Issue 3`_ (Timestamps) or `SECoP Issue 7`_ (Time Synchronization)
|
||||
|
||||
Multiple Connections
|
||||
--------------------
|
||||
|
||||
A SEC node may accept only a limited number of connections, downto 1.
|
||||
However, each SEC node should support as many connections as technically
|
||||
feasible.
|
||||
|
||||
Details about how to multiplex multiple connections onto one are to be
|
||||
discussed.
|
||||
|
||||
|
||||
Descriptive Data
|
||||
----------------
|
||||
|
||||
Format of Descriptive Data
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The format of the descriptive data is JSON, as all other data in SECoP.
|
||||
|
||||
|
||||
.. for creating the railroad diagrams see: http://bottlecaps.de/rr/ui
|
||||
.. source EBNF:
|
||||
.. SEC_node_description ::= '{' (SEC_node_property ( ',' SEC_node_property)* )? '}'
|
||||
.. SEC_node_property ::= property | ( '"modules":' '[' (name ',' module_description (',' name ',' module_description)*)? ']')
|
||||
.. module_description ::= '{' (module_property ( ',' module_property)* )? '}'
|
||||
.. module_property ::= property | ( '"parameters":' '[' (name ',' properties (',' name ',' properties)*)? ']') | ( '"commands":' '[' (name ',' properties (',' name ',' properties)*)? ']')
|
||||
.. properties ::= '{' (property ( ',' property)* )? '}'
|
||||
.. property ::= (name ':' property_value)
|
||||
|
||||
SEC node description
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. image:: diagram/sec_node_description.png
|
||||
:alt: SEC_node_description ::= '{' (SEC_node_property ( ',' SEC_node_property)* )? '}'
|
||||
|
||||
SEC node property
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. image:: diagram/sec_node_property.png
|
||||
:alt: SEC_node_property ::= property | ( '"modules":' '[' (name ',' module_description (',' name ',' module_description)*)? ']')
|
||||
|
||||
module description
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. image:: diagram/module_description.png
|
||||
:alt: module_description ::= '{' (module_property ( ',' module_property)* )? '}'
|
||||
|
||||
module property
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. image:: diagram/module_property.png
|
||||
:alt: module_property ::= property | ( '"parameters":' '[' (name ',' properties (',' name ',' properties)*)? ']') | ( '"commands":' '[' (name ',' properties (',' name ',' properties)*)? ']')
|
||||
|
||||
properties
|
||||
^^^^^^^^^^
|
||||
|
||||
.. image:: diagram/properties.png
|
||||
:alt: properties ::= '{' (property ( ',' property)* )? '}'
|
||||
|
||||
property
|
||||
^^^^^^^^
|
||||
|
||||
.. image:: diagram/property.png
|
||||
:alt: property ::= (name ':' property_value)
|
||||
|
||||
|
||||
SEC Node Properties
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
there might be properties such as a timeout which are relevant for the
|
||||
communication of a SEC node.
|
||||
|
||||
- **equipment_id**
|
||||
|
||||
- **description** (mandatory, a text describing the node, in general, the first
|
||||
line is a short description (line break \\n))
|
||||
|
||||
- **firmware** (optional, a string describing the version of the SEC node software)
|
||||
|
||||
- **timeout** (optional value in seconds, a SEC node should be able to respond within
|
||||
a time well below this value. Default: 3 sec, see `SECoP issue 4`_ )
|
||||
|
||||
|
||||
Module Properties
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
- **description** (mandatory, a text describing the parameter)
|
||||
|
||||
- **visibility** (1=expert, 2=advanced, 3=user (default)), Note: this
|
||||
does not imply that the access is controlled. It may just be a
|
||||
hint to the UI for the amount of exposed modules. (optional)
|
||||
|
||||
- **interface\_class** (a list of classes for the module, for example
|
||||
["Temperature", "DrivableWithRamp", "Drivable", "Readable"]),
|
||||
mandatory
|
||||
|
||||
- **group** (optional, identifier, may contain ':' which may be interpreted as path separator)
|
||||
(*see* `SECoP issue 8`_)
|
||||
|
||||
- **meaning**, **importance** (*see* `SECoP issue 9`_)
|
||||
|
||||
|
||||
Parameter Properties
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- **description** (mandatory, a text describing the parameter, mandatory)
|
||||
|
||||
- **readonly** (mandatory)
|
||||
|
||||
- **datatype** (mandatory, see `Data Types`_)
|
||||
|
||||
- **unit** (default: unitless, should be given, if meaningfull, empty string: unit is one)
|
||||
|
||||
- **visibility** (3=expert, 2=advanced, 1=user (default)), Note: this
|
||||
does not imply that the access is controlled. It may just be a
|
||||
hint to the UI for the amount of exposed parameters. (optional)
|
||||
|
||||
- **group** (optional, identifier, may contain ':' which may be interpreted as path separator)
|
||||
(*see* `SECoP issue 8`_)
|
||||
|
||||
Data Types
|
||||
----------
|
||||
|
||||
double
|
||||
~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["double"] *or*
|
||||
| ["double", <min>] *or*
|
||||
| ["double", <min>, <max>]
|
||||
|
|
||||
| if <max> is not given or null, there is no upper limit
|
||||
| if <min> is null or not given, there is no lower limit
|
||||
|
||||
* - Transport example
|
||||
- | 3.14159265
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | double
|
||||
|
||||
int
|
||||
~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["int"] *or*
|
||||
| ["int", <min>] *or*
|
||||
| ["int", <min>, <max>]
|
||||
|
|
||||
| if <max> is not given or null, there is no upper limit
|
||||
| if <min> is null or not given, there is no lower limit
|
||||
|
||||
* - Transport example
|
||||
- | -55
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | int64_t
|
||||
|
||||
bool
|
||||
~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["bool"]
|
||||
|
||||
* - Transport example
|
||||
- | true
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | int64_t
|
||||
|
||||
|
||||
enum
|
||||
~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["enum", {<name> : <value>, ....}]
|
||||
|
||||
* - Transport example
|
||||
- | 2
|
||||
|
||||
* - Datatype in C/C++
|
||||
- | int64_t
|
||||
|
||||
|
||||
string
|
||||
~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["string"] *or*
|
||||
| ["string", <max len>] *or*
|
||||
| ["string", <max len>, <min len>]
|
||||
|
|
||||
| if <max len> is not given, it is assumed as 255.
|
||||
| if <min len> is not given, it is assumed as 0.
|
||||
| if the string is UTF-8 encoded, the length is counting the number of bytes, not characters
|
||||
|
||||
* - Transport example
|
||||
- | "hello!"
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | char \*
|
||||
|
||||
blob
|
||||
~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["blob", <max len>] *or*
|
||||
| ["blob", <max len>, <min len>]
|
||||
|
|
||||
| if <min len> is not given, it is assumed as 0.
|
||||
|
||||
* - Transport example
|
||||
- | "AA==" (base64 encoded)
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | struct {int64_t len, char \*data}
|
||||
|
||||
array
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["array", <basic type>, <max len>] *or*
|
||||
| ["array", <basic type>, <max len>, <min len>]
|
||||
|
|
||||
| if <min len> is not given, it is assumed as 0.
|
||||
| the length is the number of elements
|
||||
|
||||
* - Transport example
|
||||
- | [3,4,7,2,1]
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | <basic_datatype>[]
|
||||
|
||||
tuple
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["tuple", [<datatype>, <datatype>, ...]]
|
||||
|
||||
* - Transport example
|
||||
- | [0,"idle"]
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | struct
|
||||
|
||||
struct
|
||||
~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 80
|
||||
:stub-columns: 1
|
||||
|
||||
* - Datatype
|
||||
- | ["struct", {<name> : <datatype>, <name>: <datatype>, ....}]
|
||||
|
||||
* - Transport example
|
||||
- | {"x": 0, "y": 1}
|
||||
|
||||
* - Datatype in C/C++ API
|
||||
- | struct
|
||||
|
|
||||
| might be null
|
||||
|
||||
.. _`SECoP Issue 2`: SECoP_Issues/issue_2.html
|
||||
.. _`SECoP Issue 3`: SECoP_Issues/issue_3.html
|
||||
.. _`SECoP Issue 4`: SECoP_Issues/issue_4.html
|
||||
.. _`SECoP issue 5`: SECoP_issues/issue_5.html
|
||||
.. _`SECoP Issue 6`: SECoP_Issues/issue_6.html
|
||||
.. _`SECoP Issue 7`: SECoP_Issues/issue_7.html
|
||||
.. _`SECoP issue 8`: SECoP_issues/issue_8.html
|
||||
.. _`SECoP issue 9`: SECoP_issues/issue_9.html
|
@ -1,7 +0,0 @@
|
||||
Timeformat
|
||||
==========
|
||||
|
||||
* format goes to 'timestamp since epoch as double with a resolution of at least 1ms'
|
||||
* SEC-node-property: timestamp is accurate or relative
|
||||
* Or: extend pong response contains the localtime (formatted as a timestamp)
|
||||
|
@ -1,101 +0,0 @@
|
||||
=========
|
||||
Todo List
|
||||
=========
|
||||
|
||||
Open questions
|
||||
==============
|
||||
|
||||
* Datatype for a mapping (like the calibration for the amagnet)
|
||||
* How to set a Mapping or an enum (with all the name-value mappings) in the configfile?
|
||||
* use toml vs. ini parser?
|
||||
* error handling should be more consistent
|
||||
* error-info stuff should be consistent
|
||||
* dynamic device creation / modification (i.e. how to set the mapping of an enum during runtime?)
|
||||
* propagation of units from main value to params
|
||||
* switch params+cmds to 'accessibles'/attributes and keep in orderdDict?
|
||||
-> needs Datatype for a function
|
||||
* datatype for funcion: is argin a list anyway, or just one (structured) argument?
|
||||
(so far we use a list and argout is a single datatype (which may be stuctured))
|
||||
* polling: vendor specific or do we propose a common way to handle it?
|
||||
(playground uses a per-device pollinterval. params may be polled less often)
|
||||
* interface classes !!! (maybe with feature mixins like WindowTimeout?)
|
||||
* hardware access: unify? how?
|
||||
* demo-hardware?
|
||||
* If more than one connection exists: shall all events be relayed to all listeners?
|
||||
* how about WRITE/COMMAND replies? Shall they go to all connected clients?
|
||||
* structure of descriptive data needs to be specified
|
||||
* same for JSON_stuff for Error Messages
|
||||
* 'changed' may be 'readback'
|
||||
* 'change' may be 'write'
|
||||
* 'read' may be 'poll'
|
||||
* the whole message may be json object (bigger, uglier to read)
|
||||
* which events are broadcast or unicast?
|
||||
* do we need a way to correlate a reply with a request?
|
||||
|
||||
|
||||
Todos
|
||||
=====
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
||||
* stronger structure insides src
|
||||
|
||||
* src/server for everything server related
|
||||
* src/client for everything client related (ProxyDevice!)
|
||||
* src/protocol for protocol specific things
|
||||
|
||||
* need subtree for different implementations to play with
|
||||
|
||||
* src/lib for helpers and other stuff
|
||||
|
||||
* possibly a parallel src tree for cpp version
|
||||
|
||||
|
||||
Client
|
||||
------
|
||||
|
||||
* maybe start with a python shell and some import magic
|
||||
* later a GUI may be a good idea
|
||||
* client: one connection for each device?
|
||||
* another connection for async data?
|
||||
|
||||
|
||||
Server
|
||||
------
|
||||
|
||||
* rewrite MessageHandler to be agnostic of server
|
||||
* move encoding to interface
|
||||
* allow multiple interfaces per server
|
||||
* fix error handling an make it consistent
|
||||
|
||||
Device framework
|
||||
----------------
|
||||
|
||||
* supply properties for PARAMS to auto-generate async data units
|
||||
* self-polling support
|
||||
* generic devicethreads
|
||||
* proxydevice
|
||||
* make get_device uri-aware
|
||||
|
||||
|
||||
Testsuite
|
||||
---------
|
||||
|
||||
* need a testsuite (pytest)
|
||||
* embedded tests inside the actual files grow difficult to maintain
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
* transfer build docu into wiki via automated jobfile
|
||||
|
||||
|
||||
|
||||
|
||||
Transfer of blobs via json
|
||||
--------------------------
|
||||
|
||||
* use base64
|
||||
|
@ -4,7 +4,5 @@ protocol stack
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
encoding
|
||||
framing/index
|
||||
interface/index
|
||||
|
Loading…
x
Reference in New Issue
Block a user