This section defines the mapping of data types defined in the IODD as well as the mapping of the representation of a duration used in various places of IO-Link which are mapped to OPC UA. It always defines the usage of an appropriate OPC UA DataType, and in some cases in addition the use of specific VariableTypes, or specific Properties of the Variable to represent specific meta data that cannot directly be mapped to OPC UA DataTypes.

The IODD data type BooleanT is mapped to the OPC UA DataType Boolean. The “True” value of IODD (0xFF) is mapped to the “True” value of OPC UA, and the “False” value of IODD (“0x00”) is mapped to the “False” value of OPC UA.

In case both SingleValue elements are provided in the IODD, and the value can directly be mapped to a Variable (see 12.3), the VariableType TwoStateDiscreteType is used. The TrueState Property contains the SingleValue representing “True” (see 13) and the FalseState Property contains the SingleValue representing “False”.

In case only one SingleValue element is provided in the IODD, and the value can directly be mapped to a Variable (see 12.3), the VariableType TwoStateDiscreteType is used as described above, with the limitation, that the text field of the Property representing the missing state contains an empty string.

In case no SingleValue element is provided in the IODD, and the value can directly be mapped to a Variable (see 12.3), the VariableType BaseDataVariableType is used.

The IODD data types IntegerT and UIntegerT are mapped to OPC UA DataTypes in different ways, depending on various elements of the IODD.

  1. If no SingleValue and no ValueRange is defined the DataType depends on the bitLength according to Table 63. If the value can directly be mapped to a Variable (see 12.3), the VariableType BaseDataVariableType is used. If the bitLength does not directly fit into an OPC UA DataType (all bitLengths except 8, 16, 32 and 64) the Variable shall contain a Property called InstrumentRange as defined in OPC 10000-8 for AnalogItemVariableType using the same BrowseName and DataType. In case of an unsigned integer the low value shall be 0 and the high value according to the bitLength (e.g. 127 for bitLength 7). In case of a signed integer the low and high value shall be according to the bitLength (e.g. bitLength 7 leads to low = -63 and high = 63).

Table 63 – Mapping of Integer and UInteger data types

IO-Link data type

IO-Link bitLength

OPC UA DataType

UIntegerT

2..8

Byte

9..16

UInt16

17..32

UInt32

33..64

UInt64

IntegerT

2..8

SByte

9..16

Int16

17..32

Int32

33..64

Int64

  1. If no SingleValue and exactly one ValueRange is defined, the same mapping as defined in (1) is used, except for the InstrumentRange Property. The InstrumentRange shall always be provided and be filled according to the ValueRange definition.
  2. If at least one SingleValue is defined and no ValueRange is defined:
  3. If all SingleValue values fit into the range of an Int32, an OPC UA Enumeration DataType is created, containing all SingleValue entries of the IODD definition in the EnumValues Property (see section 13). If the value can directly be mapped to a Variable (see section 12.3), the VariableType BaseDataVariableType shall be used
  4. If not all SingleValue values fit into the range of an Int32, the same mapping as defined in (1) is used with the following exceptions. If the value can directly be mapped to a Variable (see section 12.3), the VariableType MultiStateValueDiscreteType shall be used, and the EnumValues are filled according to the SingleValue entries (see section 13). The InstrumentRange Property is provided as according to (1).
  5. If no SingleValue and more than one ValueRange is defined the same mapping as defined in (1) is used with the following exceptions. If the value can directly be mapped to a Variable (see section 12.3), in addition to potentially providing the InstrumentRange Property (depending on the bitLength) another Property InstrumentRanges (see section 13) is provided, containing an array of ranges, one entry for each ValueRange defined in the IODD.
  6. If at least one SingleValue and exactly one ValueRange is defined the same mapping as defined in (2) is used with the following exceptions. If the value can directly be mapped to a Variable (see section 12.3), an additional Property EnumValues (same as defined on MultiStateValueDiscreteType in OPC 10000-8) is provided, with one entry for each SingleValue (see 13).
  7. If at least one SingleValue and more than one ValueRange is defined the same mapping as defined in (1) is used with the following exceptions. If the value can directly be mapped to a Variable (see section 12.3), an additional Property EnumValues (same as defined on MultiStateValueDiscreteType in OPC 10000-8) is provided, with one entry for each SingleValue defined in the IODD, and in addition to potentially providing the InstrumentRange Property (depending on the bitLength) another Property InstrumentRanges (see section 13) is provided, containing an array of ranges, one entry for each ValueRange defined in the IODD.

Note: Due to the meta data provided in the IODD an OPC UA Server can already identify that a write operation to a device will fail if the value is out of range. It is recommended that OPC UA Servers already check the value to avoid unnecessary communication to the IO-Link Device.

The IODD data type FloatT and the OPC UA DataType Float follow the same specification and can directly be mapped.

In case the value can directly be mapped to a Variable (see section 12.3) the following rules apply:

  1. If no SingleValue and no ValueRange is defined, the VariableType BaseDataVariableType is used.
  2. If no SingleValue and exactly one ValueRange is defined, the VariableType BaseDataVariableType is used. The Variable shall have the additional Property InstrumentRange as defined in OPC 10000-8 for AnalogItemVariableType using the same BrowseName and DataType. The InstrumentRange shall be filled according to the ValueRange definition.
  3. If at least one SingleValue is defined and no ValueRange is defined, the VariableType MultiStateValueDiscreteType shall be used, and the EnumValues filled according to the SingleValue entries (see section 13).
  4. If no SingleValue and more than one ValueRange is defined the VariableType BaseDataVariableType is used. The Variable shall have a Property InstrumentRanges (see section 13), containing an array of ranges, one entry for each ValueRange defined in the IODD.
  5. If at least one SingleValue and exactly one ValueRange is defined the same mapping as defined in (2) is used with the following exception: An additional Property EnumValues (same as defined on MultiStateValueDiscreteType in OPC 10000-8) is provided, with one entry for each SingleValue (see section 13).
  6. If at least one SingleValue and more than one ValueRange is defined the same mapping as defined in (4) is used with the following exception: An additional Property EumValues (same as defined on MultiStateValueDiscreteType in OPC 10000-8) is provided, with one entry for each SingleValue (see section 13).

The IODD data type StringT can either use ASCII or UTF-8 encoding. It is always mapped to an OPC UA DataType String, which is UTF-8 encoded.

The mapping requires that IO-Link ASCII based strings are converted to UTF-8. Mapping an ASCII string to UTF-8 can always be done but mapping an UTF-8 string to ASCII may fail (when writing a UTF-8 string to an IO-Link Device expecting only ASCII strings). In case the OPC UA Server cannot do a transformation, the operation shall fail.

If the value can directly be mapped to a Variable (see section 12.3), the BaseDataVariableType is used, and the mandatory element fixedLength is mapped to the Property MaxStringLength defined in OPC 10000-3, and the element encoding to the Property Encoding (see section 13). If the Variable is referenced by a StdVariableRef, and the fixedLengthRestriction is defined, this needs to be used instead.

The IODD data type OctetStringT is mapped to an array of the OPC UA DataType Byte. This mapping, instead of using the OPC UA DataType ByteString, allows to always provide the length of the array. The OctetStringT provides the mandatory element fixedLength which is directly mapped to the ArrayDimensions Attribute. If the value can directly be mapped to a Variable (see section 12.3), the VariableType BaseDataVariableType is used with no additional Properties.

The IODD data type TimeT is mapped to an OPC UA DataType DateTime.

The IODD data type TimeT has a length of 8 bytes, consisting of two 32-bit unsigned integers. The bytes 1 to 4 represent the seconds starting from 1900-01-01 0.00,00 (UTC) and the bytes 5 to 8 represent the fractional part of the current second in image031.png seconds. Because the time range before 1984-01-01 0:00,00 (UTC) is in the past (where IO-Link did not exist), the time values (seconds) from 0x00000000 to 0x9DFF4400 (exclusive) are mapped to the time after 2036-02-07 6.28,16 (UTC). See IO-Link Specification for more details.

The OPC UA DataType DateTime consists of a 64-bit signed integer which represents the number of 100 nanosecond intervals (image032.png seconds) since January 1, 1601 (UTC).

The OPC UA DataType provides a larger range whereas the IO-Link data type provides a higher precision. Therefore, the following conversion rules shall apply (see OPC 10000-6). Implementers shall ensure that the time value mappings are done as exactly as possible.

Consider the borders of the IO-Link TimeT value range:

  • If the IO-Link TimeT value is equal to the smallest possible IO-Link time value (1984-01-01 0:00,00 (UTC), seconds value: 0x9DFF4400, fractional seconds value: 0), the OPC UA DateTime value shall be 0.
  • If the IO-Link TimeT value is equal to the highest possible IO-Link time value (2120-02-07 6:28,15 (UTC), seconds value: 0x9DFF4399, fractional seconds value 0xFFFFFFFF), the OPC UA DateTime value shall be 0x7FFFFFFFFFFFFFFF (maximum value for 64-bit signed integer).

If none of the rules above apply, the IO-Link TimeT rollover has to be considered:

  • If the IO-Link TimeT value is smaller than (1984-01-01 0:00,00 (UTC), seconds value: 0x9DFF4400, fractional seconds value: 0), the time base offset has to be the difference between 1601-01-01 0:00:00 and 2036-02-07 6.28,16 (UTC).
  • If the IO-Link TimeT value is bigger than (1984-01-01 0:00,00 (UTC)), the time base offset has to be the difference between 1601-01-01 0:00:00 (UTC) and 1901-01-01 0:00:00 (UTC).

The time value conversion works according to the following formula:

image033.png

Consider the borders of the IO-Link TimeT value range:

  • If the OPC UA DateTime value is equal or greater than 2120-02-07 6:28,15 (UTC), the IO-Link TimeT value shall be 2120-02-07 6:28,15 (UTC), seconds value: 0x9DFF4399, fractional seconds value 0xFFFFFFFF).
  • If the OPC UA DateTime value is equal or smaller than 1984-01-01 0:00,00 (UTC), the IO-Link TimeT value shall be 1984-01-01 0:00,00 (UTC), seconds value: 0x9DFF4400, fractional seconds value: 0).

If none of the rules above apply, the IO-Link TimeT rollover has to be considered:

  • If the OPC UA DateTime value is equal or greater than 2036-02-07 6.28,16 (UTC), the time base offset has to be the difference between 1601-01-01 0:00:00 and 2036-02-07 6.28,16 (UTC).
  • If the OPC UA DateTime value is smaller than 2036-02-07 6.28,16 (UTC), the time base offset has to be the difference between 1601-01-01 0:00:00 and 1901-01-01 0:00:00 (UTC).

The time value conversion works according to the following formulas:

image034.png

image035.png

Table 64 and Table 65 list some special values and their conversion to the other time data type. They can be used as a base set to test the conversion algorithm implementation (together with other input-output pairs).

Table 64 – OPC UA DateTime to IO-Link TimeT – Special values

Input (OPC UA DateTime)

Output (IO-Link TimeT)

Seconds value

Description

Seconds value

Date/time value before 1984/01/01 0:00:00,000AM (inclusive)

Date/time value is "truncated"

1984/01/01 00:00:00,000AM

Date/time value after 2120/02/07 06:28:15,999AM (inclusive)

Date/time value is "truncated"

2120/02/07 06:28:15,999AM

0

Minimal OPC UA DateTime value = 1601/01/01 12:00:00,000AM

1984/01/01 00:00:00,000AM

INT64_MAX (0x7FFFFFFFFFFFFFFF)

Maximal OPC UA DateTime value = 9999/12/31 11:59:59,000PM

2120/02/07 06:28:15,999AM

Table 65 – IO-Link TimeT to OPC UA DateTime – Special values

Input (IO-Link TimeT)

Output (OPC UA DateTime)

Seconds value

Description

Seconds value

1984/01/01 00:00:00,000AM

Minimal IO-Link TimeT value

0

2120/02/07 06:28:15,000AM

Maximal IO-Link TimeT value

INT64_MAX

0

First number after IO-Link TimeT rollover

2036/02/07 06:28:17,000AM

seconds = UINT32_MAX, fSeconds = UINT32_MAX

Last number before IO-Link TimeT rollover

2036/02/07 06:28:16,999AM

The IODD data type TimeSpanT is mapped to the OPC UA DataType Duration.

The IODD data type TimeSpanT consists of 8 bytes representing fractions of a second image036.png (seconds). See IODD Specification for more details.

The OPC UA DataType Duration consists of a Double variable representing the number of milliseconds. Fractions can be used to represent fractions of milliseconds. See OPC 10000-3 for more details.

The following rules for conversion apply. Implementers shall ensure that the time span value mappings are done as exactly as possible.

As the range of the OPC UA Duration values is bigger than the IO-Link TimeSpanT value, the following conversion formula can be applied without restrictions:

image037.png

If the OPC UA Duration value is bigger than the maximum IO-Link TimeSpanT value (image038.png) converted to milliseconds (image039.png), the IO-Link TimeSpanT value has to be the maximum value for 64-bit unsigned integer 0xFFFFFFFFFFFFFFFF.

If the OPC UA Duration value fits into this range, the following conversion formula shall be applied:

image040.png

IO-Link uses in several places an octet to represent a duration in ms (e.g. MasterCycleTime and OffsetTime). As a time base and a multiplier is used, not all possible values are represented. The OPC UA DataType Duration uses a higher resolution.

If the client writes a value that cannot exactly be mapped, the server shall use the next possible lower value.

If the client tries to write a value outside the allowed range (either because of the larger size of the DataType or based on further limitations defined by the IO-Link Specification), the server shall return the error code “Bad_OutOfRange”.

In IODDs data types can either be used to represent the structure of a variable and this variable is mapped to an OPC UA Variable (see section 7.3.6), or an IODD data type is used in the context of an array or record. The following subsections describe the mapping, including whether an OPC UA Variable is used as sub-variable.

For each IODD Record a new OPC UA DataType as subtype of Structure is created.

  • The NodeId of the new DataType is composed of the NodeId of the ObjectType generated for the IODD (see section 7.3.2) and the Record/@id (“<ObjectTypeId>||<Record id>”).
  • The BrowseName and DisplayName are server-specific. It is recommended to use the Name element of the Variable in the IODD (default language English resolved textId) and “DataType” as postfix. For example, when the Variable Name has the textId “V_N_autosafeparameter”, which is defined as “autosafe parameter” in the IODD as default, the DataType BrowseName is “autosafe parameterDataType”. The DisplayName is LocalizedText, thus also different locales can be provided, using the corresponding texts of the IODD for the different locales.
  • The DataType shall use OPC Binary Encoding as definition. The DataTypeDefinition Attribute shall describe the structure according to the IODD and the rules defined next.
  • In the StructureDefinition (DataTypeDefinition Attribute) the field defaultEncodingId shall be “Default Binary”, the field baseDataType shall be “Structure”, and the field structureType “Structure_0”.
  • The array of fields (of type StructureField) shall be filled: For each IODD RecordItem defined in the IODD an entry shall be made with the following rules:
  • The Name of the IODD RecordItem (default language English resolved textId) shall map to the field name of StructureField
  • The Description of the IODD RecordItem shall map to the field description of StructureField
  • The data type of the IODD RecordItem shall map to the dataType of StructureField following Table 66

Table 66 – Mapping of data types used in IODD Record

IO-Link data type

OPC UA DataType

Remark

IntegerT

Specific Integer or Enumeration DataType

Details see section 12.2.2

UIntegerT

Specific UInteger or Enumeration DataType

Details see section 12.2.2

Float32T

Float

Details see section 12.2.3

BooleanT

Boolean

Details see section 12.2.1

OctetStringT

Byte[]

Details see section 12.2.5

StringT

String

Details see section 12.2.4

TimeT

DateTime

Details see section 12.2.6

TimeSpanT

Duration

Details see section 12.2.7.2

  • The field valueRank shall be “Scalar”
  • The field arrayDimensions shall be null, except for the OctetStringT data type mapping, where the fixedLength element is mapped to arrayDimensions
  • The field maxStringLength shall contain the fixedLength for Strings, otherwise “0”
  • The field isOptional shall be “False”

In addition to the structured DataType more things need to be considered. If the new defined Structure DataType is used in an OPC UA Variable, the following rules apply.

  • If all entries of the IODD Record are readable (RO or RW), the Variable becomes readable, otherwise the Variable as such is not readable.
  • If all entries of the IODD Record are writable (WO or RW), the Variable becomes writeable, otherwise the Variable as such is not writeable.
  • If the IODD Record has “subindexAccessSupported” to “True”, each entry of the structure is also exposed as subvariables following the general rules (e.g. for IntegerT, which might lead to an Enum DataType or usage of specific VariableTypes). If the individual entry is readable, the Variable becomes readable, if the individual entry is writable the Variable becomes writeable.
  • If the IODD Record has “subindexAccessSupported” to “False”, but it contains entries that would map to Variables with additional Properties, those entries shall be exposed as subvariables following the general rules (because of the meta data). If the whole record is readable, they shall become readable but not writeable, otherwise they become neither readable nor writeable. Such subvariables shall be created for all StringT, and some IntegerT, UIntegerT, FloatT, and BooleanT (depending whether the concrete mapping would create a Property on the Variable). If does not need to be provided for OctetStringT, TimeT, and TimeSpanT.
  • If an entry of the IODD Record is referenced by a RecordItemRef it shall be exposed as sub-variable, even if the RecordItemRef is in an optional IODD Menu.

Note that a VariableRef and RecordItemRef defines additional characteristics (see 7.3). Those need to be considered as well.

An IODD variable having the IODD data type ArrayT is mapped to an OPC UA Variable with ValueRank OneDimensionalArray.

The data type used in the array of the IODD is the base for the mapping of the data type to OPC UA (see 12.2). That does include the VariableType to use and what Properties on the Variable shall exist.

The ValueRank Attribute of the OPC UA Variable shall be OneDimensionalArray.

The ArrayDimensions Attribute of the OPC UA Variable shall be an array with exactly one entry. The value of that entry shall be the size element of the IODD Variable.

This DataType is an enumeration that defines the encoding of the string used in the IO-Link Device. Its values are defined in Table 67.

Table 67 – EncodingEnum Values

Value

Description

ASCII_0

The string is encoded as ASCII.

UTF8_1

The string is encoded as UTF-8.

Its representation in the AddressSpace is defined in Table 68.

Table 68 – EncodingEnum Definition

Attributes

Value

BrowseName

EncodingEnum

Subtype of the Enumeration DataType defined in OPC 10000-5