5. Data Info#

SECoP defines a very flexible data typing system. Data info structures are used to describe the possible values of parameters and how they are serialized. They may also impose restrictions on the usable values or amount of data. The data info structure consists of the name of the datatype augmented by data properties to pinpoint the exact meaning of the data to be described.

SECoP defines some basic data types for numeric quantities, like double, scaled and int. An enum is defined for convenience of not having to remember the meaning of values from a reduced set. A bool datatype is similar to a predefined Enum, but uses the JSON values true and false. For non-numeric types, a string and a blob are defined as well.

Furthermore, SECoP not only defines basic data types, but also structured datatypes. tuple allows aggregation of a fixed amount of values with different datatypes in an ordered way to be used as one. array stores a variable number of data elements having the same datatype. struct is comparable to tuples, with the difference of using named entries whose order is irrelevant during transport.

For data types that specify limits, they are always inclusive, i.e. the value is allowed to be one of the limit values. Also, both limits may be set to the same value, in which case there is just one allowed value.

All data info structures are specified in the descriptive data in the following generic form:

datatype ::= '{' datatype-name ':' '{' ( datatype-property ( ',' datatype-property )* )? '}'

Here is an overview of all defined data types:

Depending on the data type, there are different sets of data properties available.

5.1. Floating Point Numbers: double#

Datatype to be used for all physical quantities.

The ECS SHOULD internally use IEEE-754 double floating point values and MUST support AT LEAST the full IEEE-754 single float value range and precision. However, NaN, infinity and denormalized numbers do not need to be supported, as JSON can’t transport those ‘values’.

If the relative resolution is not given or not better than 1.2e-7, single precision floats may be used in the ECS.

Related issue: SECoP Issue 042 Requirements of datatypes

5.1.1. Optional Data Properties#

"min"

Lower limit. If min is omitted, there is no lower limit.

"max"

Upper limit. If max is omitted, there is no upper limit.

"unit"

String giving the unit of the parameter.

SHOULD be given, if meaningful. The quantity is unitless if unit is omitted or the empty string. Preferably SI units (including prefix) SHOULD be used.

Related issue: SECoP Issue 043 Parameters and units

"absolute_resolution"

A JSON number specifying the smallest difference between distinct values. Default value: 0.

"relative_resolution"

A JSON number specifying the smallest relative difference between distinct values:

abs(a - b) <= relative_resolution * max(abs(a), abs(b))

Default value: 1.2e-7 (enough for single precision floats).

If both absolute_resolution and relative_resolution are given, the expected resolution is:

max(absolute_resolution, abs(value) * relative_resolution)

Related issue: SECoP Issue 049 Precision of Floating Point Values

"fmtstr"

A C-style format string as a hint on how to format numeric parameters for the user. Default value: "%.6g".

The string must obey the following syntax:

fmtstr ::= "%" "." [1-9]? [0-9] ( "e" | "f" | "g" )

5.1.2. Example#

{"type": "double", "min": 0, "max": 100, "fmtstr": "%.3f"}

5.1.3. Transport#

As a JSON number.

Example: 3.14159265

5.2. Scaled Integer: scaled#

Scaled integers are transported as integers, but the physical value is a floating point value. It is up to the client to perform the conversion when reading/writing. The main motivation for this datatype is for SEC nodes with limited capabilities, where floating point calculation is a major effort.

Related issue: SECoP Issue 044 Scaled integers

5.2.1. Mandatory Data Properties#

"scale"

A (numeric) scale factor to be multiplied with the transported integer.

"min", "max"

The limits of the transported integer, min <= max. The limits of the represented floating point value are min*scale and max*scale.

5.2.2. Optional Data Properties#

"unit"

String giving the unit of the paramete, as for double.

"absolute_resolution"

A JSON number specifying the smallest difference between distinct values.

Default value: <scale>

"relative_resolution"

A JSON number specifying the smallest relative difference between distinct values, as for double.

"fmtstr"

A string as a hint on how to format values (after conversion) for the user. Default value: "%.<n>f" where <n> = max(0, -floor(log10(scale))).

The string must obey the same syntax as above for double.

5.2.3. Example#

{"type": "scaled", "scale": 0.1, "min": 0, "max": 2500}

i.e. a value between 0.0 and 250.0.

5.2.4. Transport#

As an integer JSON number.

Example: 1255 meaning 125.5 in the above example.

5.3. Integer: int#

Datatype to be used for integer numbers. For any physical quantity double or scaled SHOULD be used. An integer SHOULD have no unit and it SHOULD be representable with signed 24 bits, i.e. all integers SHOULD fit inside -224 … 224, as some JSON libraries might parse JSON numbers with 32bit float too.

5.3.1. Mandatory Data Properties#

"min", "max"

Integer limits, <min> <= <max>.

5.3.2. Optional Data Properties#

"unit"

A string giving the unit of the parameter, as for double.

5.3.3. Example#

{"type": "int", "min": 0, "max": 100}

5.3.4. Transport#

As a JSON number.

Example: -55

5.4. Boolean: bool#

5.4.1. Syntax#

{"type": "bool"}

5.4.2. Transport#

As JSON true or false.

5.5. Enumerated Type: enum#

5.5.1. Mandatory Data Property#

"members"

A JSON object giving all possible values: {<name>: <value>, ....}

names are strings, values are (preferably small) integers. Both names and values MUST be unique within an enum.

5.5.2. Example#

{"type": "enum", "members": {"IDLE": 100, "WARN": 200, "BUSY": 300, "ERROR": 400}}

5.5.3. Transport#

As a JSON-number. The client may perform a mapping back to the name.

Example: 200

5.6. String: string#

5.6.1. Optional data properties#

"maxchars"

The maximum length of the string in UTF-8 code points, counting the number of characters (not bytes).

"minchars"

The minimum length, default is 0.

"isUTF8"

Boolean specifying if the UTF-8 character set is allowed for values, or if the value is allowed only to contain 7-bit ASCII characters (i.e. only code points < 128), each occupying a single byte.

Defaults to False if not given.

5.6.2. Example#

{"type": "string", "maxchars": 80}

5.6.3. Transport#

As a JSON string.

Example: "Hello\n\u2343World!"

5.7. Binary Large Object: blob#

5.7.1. Mandatory Data Property#

"maxbytes"

The maximum length, counting the number of bytes (not the size of the encoded string).

5.7.2. Optional Data Property#

"minbytes"

The minimum length, default is 0.

5.7.3. Example#

{"type": "blob", "min": 1, "max": 64}

5.7.4. Transport#

As a single-line base-64 (see RFC 4648) encoded JSON string.

Example: "AA==" (a single, zero valued byte)

5.8. Sequence of Uniformly Typed Items: array#

5.8.1. Mandatory Data Properties#

"members"

A nested datainfo, giving the datatype of the elements.

"maxlen"

The maximum length, counting the number of elements.

5.8.2. Optional Data Property#

"minlen"

The minimum length, default is 0.

5.8.3. Example#

{"type": "array", "min": 3, "max": 10, "members": {"type": "int", "min": 0, "max": 9}}

5.8.4. Transport#

As a JSON array.

example: [3,4,7,2,1]

5.9. Finite Sequence of Items with Individually Typed Items: tuple#

5.9.1. Mandatory Data Property#

"members"

A JSON array listing the datatype for each member. This also gives the number of members.

5.9.2. Example#

{"type": "tuple", "members": [{"type": "int", "min": 0, "max": 999}, {"type": "string", "maxchars": 80}]}

5.9.3. Transport#

As a JSON array.

Example: [300,"accelerating"]

5.10. Collection of Named Items: struct#

5.10.1. Mandatory Data Property#

"members"

A JSON object containing the names and datatypes of the members.

5.10.2. Optional Data Property#

"optional"

A JSON list giving the names of optional struct elements.

In ‘change’ and ‘do’ commands, the ECS might omit these elements, all other elements must be given. The effect of a ‘change’ action with omitted elements should be the same as if the current values of these elements would have been sent with it. The effect of a ‘do’ action with omitted elements is defined by the implementation.

In all other messages (i.e. in replies and updates), all elements have to be given.

5.10.3. Example#

{"type": "struct", "members": {"y": {"type": "double"},
                               "x": {"type": "enum", "members": {"On": 1, "Off": 0}}}}

5.10.4. Transport#

As a JSON object.

Example: {"x": 0.5, "y": 1}

Related issue: SECoP Issue 035 Partial Structs

5.11. Commands: command#

If an accessible is a command, its main datatype is command. Argument and result data are described within.

5.11.1. Optional Data Properties#

"argument"

The datatype of the single argument, or null.

Only one argument is allowed, but it can be a structural datatype with multiple values (struct, tuple or array). If such encapsulation or data grouping is needed, a struct SHOULD be used.

"result"

The datatype of the single result, or null.

The meaning of result and argument(s) SHOULD be written down in the description of the command.

5.11.2. Example#

{"type": "command", "argument": {"type": "bool"}, "result": {"type": "int"}}

5.11.3. Transport#

Command values are not transported as such. But commands may be called (i.e. executed) by an ECS. Example:

> do module:invert true
< done module:invert [72,{t:123456789.2}]