Improve doc.

Change-Id: I0b25fd1c645a47084fb7fda1bbb7d41a2d10dcbb
This commit is contained in:
Alexander Lenz 2017-09-11 17:18:01 +02:00
parent cf3fabfa0f
commit 77b01404d9
56 changed files with 52 additions and 1297 deletions

2
.gitignore vendored
View File

@ -10,4 +10,4 @@ RELEASE-VERSION
build build
# Sphinx # Sphinx
doc/srcdoc/_build doc/_build

View File

@ -9,10 +9,8 @@ clean:
@rm -rf html @rm -rf html
@mkdir html @mkdir html
doc: doc/*.md doc:
@echo "Generating html tree" $(MAKE) -C doc html
@bin/make_doc.py
$(MAKE) -C doc/srcdoc html
demo: demo:
@bin/secop-server -q demo & @bin/secop-server -q demo &

View File

@ -1,315 +0,0 @@
## A SECoP Syntax for Demonstration
I feel it is very hard to explain in a talk what we are talking
about when discussing the concepts of SECoP. Would it not be easier
with an example syntax and an example SEC node? That is why I
created a simple syntax, which is on one hand easily understandable
by humans and on the other hand fulfills the requirements for a real syntax.
### An Example of an SEC Node with the Demo Syntax
We have 2 main devices: sample temperature and magnetic field.
> ts
ts=9.887
> mf
mf=5.1
We have some additional devices, coil temperature of upper and lower coil.
> tc1
tc1=2.23
> tc2
tc2=2.311
When we use the term "device" here, we do not mean a device in the sense of a
cryomagnet or a furnace. For SECoP, roughly any physical quantity which may
be of interest to the experimentalist, is its own device.
We can use wildcards to see the values of all devices at once.
> *
ts=9.887
mf=5.1
tc1=2.23
tc2=2.311
label='Cryomagnet MX15; at 9.887 K; Persistent at 5.1 Tesla'
The "> " is not part of the syntax, it is just indicating the request.
A request is always one line.
A reply might contain several lines and always ends with an empty line.
The last device here is a text displayed on the SE computer. It may not be
very useful, but it demonstrates that a device value may also be a text.
A device has parameters. The main parameter is its value. The value parameter
is just omitted in the path. We can list the the parameters and its values
with the following command:
> mf:*
mf=5.13
mf:status=0
mf:target=14.9
mf:ramp=0.4
mf:set_point=5.13
mf:persistent_mode=0
mf:switch_heater=1
If we want to change the field we have to set its target value:
> mf:target=12
mf:target=12.0
> mf:*
mf=5.13
mf:status=1
mf:target=12.0
mf:ramp=0.4
mf:set_point=5.13
mf:persistent_mode=0
mf:switch_heater=1
The status is indicating the state of the device. 0 means idle, 1 means busy
(running to the target).
A parameter has properties. The 'value' property is implicit, its just
omitted in the path:
> mf:status:*
mf:status=0
mf:status:value_names=0:idle,1:busy,2:error
mf:status:type=int
mf:status:t=2016-08-23 14:55:45.254348
Please notice the property "value_names" indicating the meaning of the status
values.
> mf:target:*
mf:target=12.0
mf:target:writable=1
mf:target:unit=T
mf:target:type=float
mf:target:t=2016-08-23 14:55:44.658749
The last property 't' is the timestamp. If the client want to record timestamps,
it can enable it for all device or parameter readings:
> :reply_items=t
:reply_items=t
> *
ts=9.867;t=2016-08-23 14:55:44.655862
mf=5.13;t=2016-08-23 14:55:44.656032
tc1=2.23;t=2016-08-23 14:55:44.656112
tc2=2.311;t=2016-08-23 14:55:44.656147
label='Cryomagnet MX15; at 9.867 K; Ramping at 5.13 Tesla';t=2016-08-23 14:55:44.656183
There is also a list command showing the devices (and parameters) without
values. I am not sure if we really need that, as we can just use a wildcard
read command and throw away the values.
> !*
ts
mf
tc1
tc2
label
> !ts:*
ts
ts:status
ts:target
ts:ramp
ts:use_ramp
ts:set_point
ts:heater_power
ts:raw_sensor
The property "meaning" indicates the meaning of the most important devices.
We can list all the devices which have a "meaning" property
> *::meaning
ts::meaning=temperature
mf::meaning=magnetic_field
> Markus: We have more things to tell here.
As a last example: the ultimate command to get everything:
> *:*:*
ts=9.887
ts::meaning=temperature
ts::unit=K
ts::description='VTI sensor (15 Tesla magnet)\ncalibration: X28611'
ts::type=float
ts::t=2016-08-23 14:55:44.655862
ts:status=0
ts:status:type=int
ts:status:t=2016-08-23 14:55:44.655946
ts:target=10.0
ts:target:writable=1
ts:target:unit=K
ts:target:type=float
ts:target:t=2016-08-23 14:55:44.655959
ts:ramp=0.0
ts:ramp:writable=1
ts:ramp:unit=K/min
ts:ramp:type=float
ts:ramp:t=2016-08-23 14:55:44.655972
ts:use_ramp=0
ts:use_ramp:type=int
ts:use_ramp:t=2016-08-23 14:55:44.655984
ts:set_point=10.0
ts:set_point:unit=K
ts:set_point:type=float
ts:set_point:t=2016-08-23 14:55:44.655995
ts:heater_power=0.154
ts:heater_power:unit=W
ts:heater_power:type=float
ts:heater_power:t=2016-08-23 14:55:44.656006
ts:raw_sensor=1876.3
ts:raw_sensor:unit=Ohm
ts:raw_sensor:type=float
ts:raw_sensor:t=2016-08-23 14:55:44.656018
mf=5.13
mf::meaning=magnetic_field
mf::unit=T
mf::description=magnetic field (15 Tesla magnet)
mf::type=float
mf::t=2016-08-23 14:55:44.656032
mf:status=0
mf:status:type=int
mf:status:t=2016-08-23 14:55:44.656044
mf:target=12.0
mf:target:writable=1
mf:target:unit=T
mf:target:type=float
mf:target:t=2016-08-23 14:55:44.658749
mf:ramp=0.4
mf:ramp:writable=1
mf:ramp:unit=T/min
mf:ramp:type=float
mf:ramp:t=2016-08-23 14:55:44.656066
mf:set_point=5.13
mf:set_point:unit=T
mf:set_point:type=float
mf:set_point:t=2016-08-23 14:55:44.656077
mf:persistent_mode=0
mf:persistent_mode:type=int
mf:persistent_mode:t=2016-08-23 14:55:44.656088
mf:switch_heater=1
mf:switch_heater:type=int
mf:switch_heater:t=2016-08-23 14:55:44.656099
tc1=2.23
tc1::unit=K
tc1::description='top coil (15 Tesla magnet)\ncalibration: X30906'
tc1::type=float
tc1::t=2016-08-23 14:55:44.656112
tc1:status=0
tc1:status:type=int
tc1:status:t=2016-08-23 14:55:44.656123
tc1:raw_sensor=5434.0
tc1:raw_sensor:unit=Ohm
tc1:raw_sensor:type=float
tc1:raw_sensor:t=2016-08-23 14:55:44.656134
tc2=2.311
tc2::unit=K
tc2::description='bottom coil (15 Tesla magnet)\ncalibration: C103'
tc2::type=float
tc2::t=2016-08-23 14:55:44.656147
tc2:status=0
tc2:status:type=int
tc2:status:t=2016-08-23 14:55:44.656159
tc2:raw_sensor=4834.5
tc2:raw_sensor:unit=Ohm
tc2:raw_sensor:type=float
tc2:raw_sensor:t=2016-08-23 14:55:44.656169
label='Cryomagnet MX15; Ramping'
label::writable=1
label::type=string
label::t=2016-08-23 14:55:44.656183
.:reply_items=t
.:reply_items:writable=1
.:reply_items:type=string
.:reply_items:t=2016-08-23 14:55:44.659617
.:compact_output=0
.:compact_output:writable=1
.:compact_output:type=int
.:compact_output:t=2016-08-23 14:55:44.656219
The last device '.' is a dummy device to hold the parameters of a client
connection. Changing these parameters must not affect other client connections.
The experimental parameter compact_output is for compressing the result of
wildcard requests: unchanged device and parameter names are omitted.
> :compact_output=1
.:compact_output=1
> *:*:*
ts=9.887
::meaning=temperature
::unit=K
::description='VTI sensor (15 Tesla magnet)\ncalibration: X28611'
::type=float
::t=2016-08-23 15:04:55.180514
:status=0
::type=int
::t=2016-08-23 15:04:55.180587
:target=10.0
::writable=1
::unit=K
::type=float
::t=2016-08-23 15:04:55.180594
:ramp=0.0
::writable=1
::unit=K/min
::type=float
::t=2016-08-23 15:04:55.180599
:use_ramp=0
::type=int
::t=2016-08-23 15:04:55.180604
:set_point=10.0
::unit=K
::type=float
::t=2016-08-23 15:04:55.180609
:heater_power=0.154
::unit=W
::type=float
::t=2016-08-23 15:04:55.180615
:raw_sensor=1876.3
::unit=Ohm
::type=float
::t=2016-08-23 15:04:55.180620
mf=5.13
::meaning=magnetic_field
::unit=T
::description=magnetic field (15 Tesla magnet)
::type=float
::t=2016-08-23 15:04:55.180626
:status=0
::type=int
::t=2016-08-23 15:04:55.180632
:target=14.9
::writable=1
::unit=T
::type=float
::t=2016-08-23 15:04:55.180637
:ramp=0.4
::writable=1
::unit=T/min
::type=float
::t=2016-08-23 15:04:55.180642
:set_point=5.13
::unit=T
...

View File

@ -1,285 +0,0 @@
## A SECoP Syntax for Demonstration
### Mapping of Messages
Please remind: replies always end with en empty line, which means that there are
2 newline characters at the end of each reply. To emphasize that, in this document
a bare '_' is shown as a replacement for the closing empty line.
#### ListDevices
> !*
<device-name1>
<device-name2>
...
<device-nameN>
_
#### ListDeviceParams
> !<device>:*
<device>:<param1>
<device>:<param2>
...
<device>:<paramN>
_
#### ReadRequest
> <device>:<param>
<device>:<param1>=<value>
_
Or, in case it is combined with timestamp (may be also sigma, unit ...). See also
below under "client parameters" / "reply_items".
> <device>:<param>
<device>:<param1>=<value>;t=<timestamp>
_
> <device>:<param>
<device>:<param1>=<value>;t=<timestamp>;s=<sigma>
_
> <device>:<param>
<device>:<param1>=<value>;t=<timestamp>;s=<sigma>;unit=<unit>
_
#### ReadPropertiesOfAllDevices
remark: for shortness the name of the value property and the preceding ':' is omitted
> *:*:*
<device1>:<param1>=<value1>
<device1>:<param1>:<prop2>=<value2>
...
<deviceN>:<paramM>:<propL>=<valueK>
_
#### ReadPropertiesOfADevice
means read properties of all parameters of a device)
> <device>:*:*
<device>:<param1>=<value1>
<device>:<param1>:<prop2>=<value2>
...
<device>:<paramN>:<propM>=<valueL>
_
#### ReadPropertiesOfAParameter
> <device>:<param>:*
<device>:<param>=<value1>
<device>:<param>:<prop2>=<value2>
...
<device>:<param>:<propN>=<valueN>
_
#### ReadSpecificProperty
> <device>:<param>:<prop>
<device>:<param>:<prop>=<value>
_
In case you want the value only, and not the timestamp etc, '.' is a placeholder for the
value property
> <device>:<param>:.
<device>:<param>:.=<value>
_
#### ReadValueNotOlderThan
Instead of this special Request, I propose to make a client parameter "max_age",
which specifies in general how old values may be to be returned from cache.
#### Write
remark: writes to other than the 'value' property are not allowed. If anyone sees a
reasonable need to make writeable properties, a WriteProperty Request/Reply should
be discussed
> <device>:<param>=<value>
<device>:<param>=<readback-value>
_
#### Command
If we want to distinguish between a write request and a command, we need also a
different syntax. It is to decide, how arguments may be structured / typed.
Should a command also send back a "return value"?
> <device>:<param> <arguments>
<device>:<param> <arguments>
_
#### Error replies
Error reply format:
~<error-specifier>~ <path or other info>
_
The error-specifier should be predefined identifer.
> tempature:target
~NoSuchCommand~ tempature
_
> temperature:taget
~NoSuchParameter~ temperature:taget
_
#### FeatureListRequest
Instead of an extra FeatureListRequest message, I propose to do have a device,
which contains some SEC node properties, with information about the SEC node,
and client parameters, which can be set by the ECS for optional
features. Remind that internally the SEC Node has to store the client parameters
separately for every client.
#### SEC Node properties
You are welcome to propose better names:
> ::implements_timestamps
::implements_timestamps=1
_
> ::implements_async_communication
::implements_async_communication=1
_
The maximum time delay for a response from the SEC Node:
> ::reply_timeout=10
::reply_timeout=10
_
SEC Node properties might be omitted for the default behaviour.
#### Client parameters
Enable transmission of timestamp and sigma with every value
> :reply_items=t,s
:reply_items=t,s
_
If a requested property is not present on a parameter, it is just omitted in the reply.
The reply_items parameter might be not be present, when the SEC node does not implement
timestamps and similar.
Update timeout (see Update message)
> :update_timeout=10
:update_timeout=10
#### SubscribeToAsyncData
In different flavors: all parameters and all devices:
> +*:*
<device1>.<param1>
...
<deviceN>.<paramM>
_
Only the values of all devices:
> +*
+<device1>
...
+<deviceN>
_
All parameters of one device:
> +<device>:*
+<device>:<param1>
...
+<device>:<paramN>
_
I think we need no special subscriptions to properties, as :reply_items should be
recognized by the updates. All other properties are not supposed to be changed during
an experiment (we might discuss this).
If an Unsubscribe Message would be implemented, it could be start with a '-'
#### Update
In order to stick to a strict request / reply mechanism I propose instead of a real
asynchronous communication to have an UpdateRequest. The reply of an UpdateRequest
might happen delayed.
- it replies immediately with a list of all subscripted updates, if some happend since
the last UpdateRequest
- if nothing has changed, the UpdateReply is sent as soon as any update happens
- if nothing happens within the time specified by :update_timeout
an empty reply is returned.
If a client detects no reply within :update_timeout plus ::reply_timeout,
it can assume the the SEC Node is dead.
The UpdateRequest may be just an empty line (my favorite) or, if you prefer an
question mark:
> ?
<device1>=<value1>
<device2>.<paramX>=<value2>
_
With no update during :update_timeout seconds, the reply would be
> ?
_
#### Additional Messages
I list here some additional messages, which could be useful, but wich were not yet
identified as special messages. They all follow the same syntax, which means that
it is probably no extra effort for the implementation.
Interestingly, we have defined ReadPropertiesOfAllDevices, but not Read a specific
property of all parameters. At least reading the value properties is useful:
> *:*
List all device classes (assuming a device property "class")
> *::class
<device1>::class=<class1>
<device2>::class=<class2>
...
<deviceN>::class=<classN>
_
The property meaning is for saying: this device is important for the experimentalist,
and has the indicated meaning. It might be used by the ECS to skip devices, which
are of no interest for non experts. Example:
> *::meaning
ts::meaning=sample temperature
mf::meaning=magnetic field
_
We might find other useful messages, which can be implemented without any additional
syntax.
#### A possible syntax extension:
Allow a comma separated list for path items:
> ts,mf
ts=1.65
mf=5.13
_
> ts::.,t,s
ts=<value>
ts::t=<timestamp>
ts::s=<sigma>
_
If somebody does not like the :reply_items mechanism, we could us the latter example
as alternative for reading values together with timestamp and sigma.

View File

@ -1,279 +0,0 @@
(Outdated!)
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

@ -1,39 +0,0 @@
------
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
# THERE IS STILL MUCH WORK TO DO! #

View File

@ -1,372 +0,0 @@
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.

View File

@ -22,7 +22,7 @@ from os import path
# sys.path.insert(0, os.path.abspath('.')) # sys.path.insert(0, os.path.abspath('.'))
# Add import path for inplace usage # Add import path for inplace usage
sys.path.insert(0, path.abspath(path.join(path.dirname(__file__), '..', '..', '..'))) sys.path.insert(0, path.abspath(path.join(path.dirname(__file__), '..', '..')))
from secop.version import get_version from secop.version import get_version

View File

@ -11,7 +11,9 @@ Protocol documentation
timeformat timeformat
modsubset modsubset
heartbeat heartbeat
jsonstruct
todo todo
notes
history history

View File

@ -1,3 +1,6 @@
JSON structure
==============
> Mit JSON Freeze meine ich nur Arrays von Objekten also: > Mit JSON Freeze meine ich nur Arrays von Objekten also:
> -Node hat ein Array von Properties und ein Array von Modulen > -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 > -Module haben ein Array von Properties, ein Array von Parametern und ein Array von Commands
@ -18,7 +21,7 @@ property = { 'property-name' : 'property-value' }
ODER ODER
==== ----
node = [ <array_of_properties>, <array_of_modules> ] node = [ <array_of_properties>, <array_of_modules> ]

View File

@ -0,0 +1,42 @@
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