reworking messages

1) start 'bin/secop-server test'
2) connect to localhost port 10767
3) enter help<enter>
4) enjoy

Change-Id: I488d5f9cdca8c91c583691ab23f541a4a8759f4e
This commit is contained in:
Enrico Faulhaber
2016-09-29 18:27:33 +02:00
parent dc2d0a10aa
commit b6af55c358
49 changed files with 3682 additions and 1034 deletions

215
doc/SECoP_Messages.md Normal file
View File

@ -0,0 +1,215 @@
SECoP Messages
==============
All Messages are formatted in the same way:
&lt;keyword&gt;[&lt;space&gt;&lt;specifier&gt;[&lt;space&gt;&lt;JSON_formatted_data&gt;]]&lt;linefeed&gt;
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"
&lt;keyword&gt; is one of a fixed list of defined keywords, &lt;specifier&gt; 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.
All 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!)
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 -&gt; Ident
* Describe -&gt; Description
* Activate Events -&gt; initial data transfer -&gt; end-of-transfer-marker
* Deactivate Async Events -&gt; confirmation
* Command &lt;module&gt;:&lt;command&gt; -&gt; confirmation -&gt; result_event
* Heartbeat &lt;nonce&gt; -&gt; Heartbeat_reply
* Change &lt;module&gt;[:&lt;param&gt;] JSON_VALUE -&gt; confirmation -&gt; readback_event
* TRIGGER &lt;module&gt;[:&lt;param&gt;] -&gt; 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 &lt;..&gt; with sensible stuff)
Identify
--------
* Request: type A: '*IDN?'
* Reply: special: 'Sine2020WP7.1&ISSE, SECoP, V2016-11-30, rc1'
* queries if SECoP protocol is supported and which version it is
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 &lt;ID&gt; {"modules":{"T1":{"baseclass":"Readable", ....'
* request the 'descriptive data'. The format needs to be better defined and
may possibly just follow the reference implementation.
&lt;ID&gt; identifies the equipment. It should be unique. Our suggestion is to use something along &lt;facility&gt;_&lt;id&gt;, 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 &lt;module&gt;:&lt;command&gt;' for commands without arguments
* Request: type C: 'do &lt;module&gt;:&lt;command&gt; JSON_argument' for commands with arguments
* Reply: type B: 'doing &lt;module&gt;:&lt;command&gt;' for commands without arguments
* Reply: type C: 'doing &lt;module&gt;:&lt;command&gt; JSON_argument' for commands with arguments
* start executing a command. When it is finished, an event is send.
Write
-----
* Request: type C: 'change &lt;module&gt;[:&lt;param&gt;] JSON_value'
* Reply: type C: 'changing &lt;module&gt;[:&lt;param&gt;] JSON_value' # direct reply
* initiate setting a new value for the module or a parameter of it.
Once this is done, the new value is confirmed by an event.
Trigger
-------
* Request: type B: 'read &lt;module&gt;[:&lt;param&gt;]'
* 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 &lt;nonce&gt;'
* Reply: type A: 'pong'
* Reply: type B: 'pong &lt;nonce&gt;'
* Replies the given argument to check the round-trip-time or to confirm that the connection is still working.
&lt;nonce&gt; may not contain &lt;space&gt;. 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 &lt;nonce&gt; 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 Command, Change or Trigger or by Activating Async Mode.
* Reply: type C: 'update &lt;module&gt;[:&lt;param&gt;] JSON_VALUE' # follows a TRIGGER
* Reply: type C: 'changed &lt;module&gt;[:&lt;param&gt;] JSON_VALUE' # follows a CHANGE
* Reply: type B: 'done &lt;module&gt;:&lt;command&gt;' # follows a COMMAND without return value
* Reply: type C: 'done &lt;module&gt;:&lt;command&gt; JSON_VALUE' # follows a COMMAND with return value
* Informs the client that a value has changed its value or that a command is finished (and what the return value, if any, was).
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!
examples:
* 'update T1 [3.479, {"t":"149128925.914882", "e":0.01924}]
* 'changed T1:p [12, {"t":"149128927.193725"}]'
* 'done T1:stop'
* 'update Vector [[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 &lt;errorclass&gt; JSON_additional_stuff'
* Following &lt;errorclass&gt; 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?"
Example
=======
<pre>
(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}]'
...
</pre>
Discussion & open Points
========================
* 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?
* ...

277
doc/messages.md Normal file
View File

@ -0,0 +1,277 @@
Struktur der Messages
=====================
Es gibt folgende Messagetypen:
* LIST (listet namen einer Ebene auf)
* READ+WRITE (addressiert einen spezifischen Wert)
* FETCH (kombiniert LIST+READ, antwort ist multi)
* COMMAND (um Befehle aufzurufen: stop(), init(),...)
* (UN)SUBSCRIBE (bucht events, bestellt sie ab, f&uuml;r devices/params)
* EVENT (ASYNC!)
* ERROR
* POLL (wie FETCH, aber fragt vorher die HW, kann dauern)
* TRIGGER (Wie POLL, aber die Antworten kommen als Events, return sofort)
Außer EVENT und ERROR (beides nur als Reply) gibts es jede Message als Request und als Reply.
Das Parsing einer Message ist eindeutig, so hat jeder reply mindestens ein '=', jede Mehrfachantwort endet mit '`#<anzahl messages>`', uswusf.
F&uuml;r das Parsing wird eine Regexp empfohlen, da die syntax nicht sonderlich parsingfreundlich ist.
Um auszuw&auml;hlen, auf welche Objekte eine Nachricht wirkt, werden folgende Argumente verwendet:
- `*` wirkt auf alle devices
- `device` wirkt auf das Device
- `device:*` wirkt auf alle parameter des gegebenen devices
- `device:param` wirkt auf den Parameter des Device
- `device:param:*` wirkt auf alle properties des gegebenen parameters
- `device:param:property` wirkt auf die property
Properties sind immer ReadOnly Softwarewerte. Somit haben WRITE, TRIGGER, (UN)SUBSCRIBE auf properties keinen sinn und sind mit einem Error zu beantworten.
(welcher? ProtokollError?=
Replies enthalten immer genau eine Antwort.
Der immer anzugebende 'Antwortwert' wird durch `=` von einer kopie des requestes abgetrennt.
F&uuml;r Multi-Antworten endet die Antwort in `#<number of replyitems>\n` statt in `\n`.
Hier ist kein '=' zus&auml;tzlich anzugeben. Nach dieser 'Er&ouml;ffnungsnachricht' kommen die angegebene Anzahl Antworten als Read-Replies.
Damit ergeben sich folgende Kombinationen (immer zuerst der Request, direkt drunter der Reply, direkt drunter die Beschreibung):
Danach die 'dringlichkeit des implementierens':
MANDATORY > RECOMMENDED > OPTIONAL
Werte sind entweder Zahlen (`1.23`) oder Strings (`"Ein String"` oder `Text`).
Solange eindeutigkeit besteht (kein '" ", ",", oder " im String) k&ouml;nnen die `"` weggelassen werden. Beispiel: unit=T
LIST
----
* 'LIST *' oder 'LIST'
* 'LIST *=mf,tc1,tc1,ts,...' oder 'LIST=mf,tc1,...'
* ListDevices: returns ',' separated list of devicenames
* MANDATORY
---------------
* 'LIST `<devname>`'
* 'LIST `<devname>`=status, target, value,...'
* ListParameters: returns ',' separated list of parameternames for a device
* MANDATORY
---------------
* 'LIST `<devname>:<paramname>`'
* 'LIST `<devname>:<paramname>`=timestamp, unit, description,...'
* ListProperties: returns ',' separated list of propertynames for a parameter
* MANDATORY
READ/WRITE
----------
* 'READ `<devname>`'
* 'READ `<devname>=<value>; [<qualname> '=' <qualvalue> ';']`'
* ReadDevice: returns current device value + qualifiers
* MANDATORY
---------
* 'READ `<devname>:<paramname>`'
* 'READ `<devname>:<paramname>=<value>; [<qualname> '=' <qualvalue> ';']`'
* ReadParameter: returns current parameter value (+ qualifiers?)
* MANDATORY
--------
* 'READ `<devname>:<paramname>:<property>`'
* 'READ `<devname>:<paramname>:<property>=<value>;`'
* ReadProperty: returns curent value of property
* RECOMMENDED
--------
* 'WRITE `<devname>=<value>`'
* 'WRITE `<devname>=<value>=<readbackvalue>; [<qualname> '=' <qualvalue> ';']`'
* WriteDevice: sets new device-value and returns read-back target value + non-empty qualifiers! (at least the `;` must be present)
* MANDATORY
--------
* 'WRITE `<devname>:<paramname>=<value>`'
* 'WRITE `<devname>:<paramname>=<value>=<readbackvalue>; [<qualname> '=' <qualvalue> ';']`'
* WriteParameter: sets new parameter-value and returns read-back value + non-empty qualifiers! (at least the `;` must be present)
* MANDATORY
COMMAND
-------
* 'COMMAND `<device>:<command>'(' [<argument> ','] ')'`'
* 'COMMAND `<device>:<command>'(' [<argument> ','] ')=' result`;'
* ExecuteCommand: f&uuml;hrt command mit den gegebenen Arguments aus.
result=(ein) R&uuml;ckgabewert, kann auch "OK" sein, falls kein R&uuml;ckgabewert definiert wurde.
* MANDATORY
commands sind parameter deren name auf '()' endet.
(oder die argumenttypen in () enth&auml;lt?)
(UN)SUBSCRIBE
-------------
* 'SUBSCRIBE `<device>`'
* 'SUBSCRIBE `<device>=OK`;'
* SubscribeDevice: subscribed auf den devicevalue (evtl auch auf den status?)
* RECOMMENDED
* possible extension: include a 'FETCH `<device>`' reply as Multi
--------
* 'SUBSCRIBE `<device>`'
* 'SUBSCRIBE `<device>=<list_of_subscribed_parameternames>`;'
* SubscribeALLParameter: subscribed alle parameter eines device
* RECOMMENDED
* possible extension: include a 'FETCH `<device>:`' reply as Multi
--------
* 'SUBSCRIBE `<device>:<param>`'
* 'SUBSCRIBE `<device>:<param>=OK`;'
* SubscribeParameter: subscribed auf den parameter
* RECOMMENDED
* possible extension: include a 'FETCH `<device>:<param>`' reply as Multi
--------
* 'UNSUBSCRIBE `<device>`'
* 'UNSUBSCRIBE `<device>=OK`;'
* UNSubscribeDevice: unsubscribed auf den devicevalue
* RECOMMENDED
* possible extension: return list of remaining subscriptions as multi
--------
* 'UNSUBSCRIBE `<device>:`'
* 'UNSUBSCRIBE `<device>:=OK`;'
* UNSubscribeALLParameter: unsubscribed alle parameter eines device
* RECOMMENDED
* possible extension: return list of remaining subscriptions as multi
--------
* 'UNSUBSCRIBE `<device>:<param>`'
* 'UNSUBSCRIBE `<device>:<param>=OK`;'
* UNSubscribeParameter: unsubscribed auf den parameter
* RECOMMENDED
* possible extension: return list of remaining subscriptions as multi
Was ist zu tun bei einem unsubscribe auf einen nicht subscribten wert?
(doppeltes unsubscribe nach subscribe, etc...)
EVENT
-----
* EVENT gibt es nicht als Request, da es nur als async reply auftaucht
* '`#3\n`EVENT READ `mf=1.2\n`EVENT READ `mf:target=2.0\n`EVENT READ `mf:status="BUSY"\n`'
* Event: sendet ein subscribed event, kann 0..N READ-replies beinhalten
* RECOMMENDED
FETCH/POLL
----------
* 'FETCH :' oder 'FETCH'
* 'FETCH `:#2\nREAD mf=1.2\nREAD ts=3.4\n`' oder 'FETCH`#2\nREAD mf=1.2\nREAD ts=3.4\n`'
* FetchDevices: reads and returns the values of all (interesting?) devices
* OPTIONAL
--------
* 'FETCH `<device>`'
* 'FETCH mf#2\nREAD mf:value=1.2\nREAD mf:status="IDLE"\n`'
* FetchDevice: reads and returns the (interesting?) parameters of a device
* OPTIONAL
--------
* 'FETCH `<device>:`'
* 'FETCH `mf:#3\nREAD mf:value=1.2\nREAD mf:target=1.2\nREAD mf:status="IDLE"\n`'
* FetchParameters: reads and returns the values of all parameters of a device
* OPTIONAL
--------
* 'FETCH `<device>:<parameter>`'
* 'FETCH `mf:value#2\nREAD mf:value:unit="T"\nREAD mf:value:type=float\n`'
* FetchParameter: reads and returns the properties of a single parameter
* OPTIONAL
--------
* 'FETCH `<device>:<parameter>:`'
* 'FETCH `mf:value:#2\nREAD mf:value:unit="T"\nREAD mf:value:type=float\n`'
* FetchProperties: reads and returns the values of all properties of a parameter
* OPTIONAL
POLL wird wie FETCH kodiert, fragt aber die HW vor der Antwort, FECTH liefert zwischengespeicherte Werte.
TRIGGER
-------
* 'TRIGGER :' oder 'TRIGGER'
* 'TRIGGER :=OK' oder 'TRIGGER=OK'
* TriggerDeviceReads: startet auslesen aller devices und &uuml;bertragen der (subscribed) values als events
* OPTIONAL
--------
* 'TRIGGER `<device>`'
* 'TRIGGER `mf=OK`'
* TriggerDeviceRead: startet auslesen eines Devices
* OPTIONAL
--------
* 'TRIGGER `<device>:`'
* 'TRIGGER `mf:=OK`'
* TriggerParameterReads: startet auslesen aller paremeter und &uuml;bertragen der subscribed parameter als events
* OPTIONAL
--------
* 'TRIGGER `<device>:<parameter>`'
* 'TRIGGER `mf:value=OK`'
* FetchProperties: reads and returns the values of all properties of a parameter
* OPTIONAL
ERROR
-----
* ERROR gibt es nicht als request, da es nur als reply auftaucht
* 'ERROR `<errorclass> "<copy of request>" [<additional text>]`'
* Error: zeigt einen Fehler an. folgende <errorclass> sind definiert:
* NoSuchDevice
* NoSuchParameter
* NoSuchCommand
* NoSuchProperty
* CommandFailed
* ReadOnly
* BadValue
* CommunicationFailed
* IsBusy
* IsError
* ProtocolError
* SyntaxError
* MANDATORY
M&ouml;glich Erweiterung: f&uuml;r device/param/property kann statt eines einzelnamens auch eine ',' separierte Liste verwendet werden.
Außerdem k&ouml;nnte auch ein '*' f&uuml;r 'ALLE' stehen.
Die Antworten sind dann auf jeden Fall als Multi zu kodieren. Beispiel:
> READ mf:target,value
> > READ mf:target,value#2
>
> > READ mf:target=1.23
>
> > READ mf:value=0.73
>

View File

@ -0,0 +1,372 @@
Simple communication protocol
=============================
| *Version 0.0.2*
| *Copyright 2012: Alexander Lenz, Dr. Enrico Faulhaber*
Table of contents
-----------------
.. contents::
.. sectnum::
Disambiguation
--------------
Device
''''''
A device is a logical part of the complete system. This may be any piece of hardware which
can be accessed seperately. Also a logical axis, implemented with multiple motors can be a device.
Parameter
'''''''''
A parameter is a device depended value which represents (usually) a physical value.
It can be read only or read-/writeable.
Messages
--------
The messages are devided into commands and responses.
A command consists of the device of interest, the relevant parameter, an operator
that specifies what should happen, and a value if neccessary.
::
Commands: <device>/<parameter><operator><value_if_any>\n
You will get a response for each command (\ **even if it failed!**\ ).
These reponses consist of an error code, the mirrored command (to verify for what command the response is related)
and a value if requested.
::
Response: <error_code> <mirrored_command><value_if_any>\n
For limitations regarding the message contents, have a look at: `Limitations`_
Operators
---------
? (Request)
'''''''''''
This operator can be used to request data.
In the most cases, you want to request the value of device parameter:
**Command**
::
<device>/<parameter>?\n
**Response**
::
<error_code> <device>/<parameter>=<value_if_success>\n
= (Set)
'''''''
This operator can be used to write a device value.
**Command**
::
<device>/<parameter>=<value>\n
**Response**
::
<error_code> <device>/<parameter>=<value>\n
Protocol error codes
--------------------
In case of an error, you get the following response:
::
<error_code> <mirrored_command>
The following errors describe errors of the protocol, not the device.
======================= ==============
**Error** **Error code**
======================= ==============
No error 0
Unknown error 1
Connection error 2
Command unknown 3
Device unknown 4
Parameter unknown 5
Format error 6
Value out of limits 7
Param not writable 8
Not allowed 9
======================= ==============
Device stati
------------
The following status codes describe the device status and can be requested via:
::
<device>/status:\n
========== ===========
**Status** **Meaning**
========== ===========
IDLE Device is alive and ready to accept commands.
BUSY Device is performing some action and therefore busy. It doesn't accept new commands. All Parameters can be read.
ERROR Something bad happened, a manual action is required. Some command could unexpectedly not be performed.
UNKNOWN Unknown device state.
========== ===========
Limitations
-----------
Naming & Formatting
'''''''''''''''''''
- Device names are all lower case and can consist of letters, numbers and underscores (no whitespace!).
- Device names consist of up to 80 characters.
- Parameter names are all lower case and can consist of letters, numbers and underscores (no whitespace!).
- Parameter names consist of up to 80 characters.
- Floating point numbers are using a decimal point (5.23).
- Lists are commma-separated and enclosed by square brackets ([entry1,entry2,entry3]).
- Strings are enclosed by single ticks ('str').
- Messages consist of up to 256 characters.
Devices
'''''''
General
"""""""
All devices have to support at least the following parameters:
**status**
This **read only** parameters describes the current device state.
It contains a list with two items.
1. A short constant status string (Have a look at: `Device stati`_)
2. A longer description which can contain any character except a comma!
**parameters**
This **read only** parameter represents a list of all available parameters of the given device.
It contains a comma seperated list with all parameter names.
Readable
""""""""
All devices which provide any type of readable value have to support the general parameters and at leas the following:
**value**
This **read only** parameter represents the current 'main value'.
It contains a single value which can be a float or integer number, or a string.
Writable
""""""""
All devices for which you can set a value have to support at least the general parameters, all parameters of `Readable`_ devices and the following:
**target**
This **read/write** parameter represents the device's target value.
It contains a single value which can be a float or integer number, or a string.
If you set the target value, the device goes into 'BUSY' state and tries to reach that value.
The current value can be requested by the 'value' parameter.
Server device
"""""""""""""
The server have to provide a device for direct communication with the protocol server.
It has to provide at least the parameters of a general device (`Devices`_) plus the following:
**devices**
A list of all available devices.
**version**
A version string which identifies the protocol version, the server implements.
The server device can be queried by omitting the <device> parameter (+ the '/').
::
devices?\n
version?\n
Examples
--------
Let's have a look at some examples:
+---------------+---------------------------------+
|**Device:** |temp_ctrl |
+---------------+---------------------------------+
|**Type:** |Temperature controller (Moveable)|
+---------------+---------------------------------+
|**Parameters:**| - status **(mandatory)** |
| | - parameters **(mandatory)** |
| | - value **(mandatory)** |
| | - target **(mandatory)** |
| | - ... |
+---------------+---------------------------------+
Requesting the current setpoint (target)
''''''''''''''''''''''''''''''''''''''''
**Command**
::
temp_ctrl/target?\n
**Response**
::
0 temp_ctrl/target=0.42\n
Setting the setpoint (target)
'''''''''''''''''''''''''''''
**Command**
::
temp_ctrl/target=0.21\n
**Response**
::
0 temp_ctrl/target=0.21\n
Setting an out-of-bounds setpoint (target)
''''''''''''''''''''''''''''''''''''''''''
**Command**
::
temp_ctrl/target=-7.5\n
**Response**
::
7 temp_ctrl/target=-7.5\n
Requesting the status
'''''''''''''''''''''
**Command**
::
temp_ctrl/status?\n
**Response**
::
0 temp_ctrl/status=BUSY,I'm ramping!\n
Requesting the device list
''''''''''''''''''''''''''
**Command**
::
/devices?\n
**Response**
::
0 /devices=temp_ctrl,another_dev1,another_dev2\n
.. Allowed extensions
------------------
Additional operators
''''''''''''''''''''
\* (Wildcard)
"""""""""""""
This operator is a little more advanced than the others.
It represents a wild card and can be combined with other operators.
The response you will get, are multiple messages which contain:
::
<error_code> <the_mirrored_command> <answer_for_the_operator>
If you want to request all parameters of a device, it will be:
**Command**
::
<device>/*?\n
**Response**
*Multiple*
::
<error_code> <device>/*? <device>/<parameter>=<value>\n
Examples
^^^^^^^^
Requesting all parameters
*************************
**Command**
::
temp_ctrl/*?\n
**Response**
::
0 temp_ctrl/*? temp_ctrl/status=BUSY,I'm ramping!\n
0 temp_ctrl/*? temp_ctrl/parameters=status,parameters,value,target\n
0 temp_ctrl/*? temp_ctrl/value=0.21\n
0 temp_ctrl/*? temp_ctrl/target=0.42\n
Recommendations
---------------
Interfaces
''''''''''
We provide some recommendations for the interface configuration when using the simple communication protocol:
Serial (RS232)
""""""""""""""
If you are using a serial connection, you should use the following configuration:
============= ==============
**Baudrate** 9600 or 115200
**Data bits** 8
**Parity** None
**Stop bits** 1
============= ==============
Network (TCP)
"""""""""""""
If you are using a TCP based network connection, you should use the following configuration:
======== =====
**Port** 14728
======== =====
Network (UDP)
"""""""""""""
We recommend not to use UDP connections at all, as the protocol was not designed for such connections.