demo syntax from Markus Zolliker, initial commit + test file
squashed together Change-Id: I11b2f4ae99abe72c3edbc83f18826df48b2ecd02
This commit is contained in:
315
doc/demo_syntax.md
Normal file
315
doc/demo_syntax.md
Normal file
@ -0,0 +1,315 @@
|
||||
## 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
|
||||
|
||||
...
|
||||
|
||||
|
285
doc/demo_syntax_mapping.md
Normal file
285
doc/demo_syntax_mapping.md
Normal file
@ -0,0 +1,285 @@
|
||||
## 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.
|
Reference in New Issue
Block a user