Adapter Protocol (eMQTT) v1.0.9
This document is valid for use with SICON.OS version 2024.x.
1. Protocol Overview
The eMQTT (embedded MQTT) protocol is based on MQTT and used for resource-limited devices that wish to be connected to the SICON system.
An internal adapter called eMQTT Adapter is instantiated for each device that uses eMQTT.
The part of the device firmware that communicates with eMQTT is called an ePlug or simply plug in this document.
The ePlug represents the IOT interface of one or more actual devices and provides a virtual connection point (called Sub-interface) for each of its possible devices. The sub-interfaces can be structured hierarchically on up to 4 levels.
Features of the eMQTT protocol:
Plug management: Establishing the MQTT connection between plugs and SICON.OS
Device management: Connecting and disconnecting of devices to the plug’s sub-interfaces.
Static data: A set of variables within the device that can be read or written on-demand (comparable to ISDUs in IO-Link devices).
Cyclic data: Live data of the device that is sent periodically to SICON.OS (comparable to process data in IO-Link devices).
Events: Push-messages transmitted spontaneously from the devices.
Reporting: Automated read-out of static data when a trigger condition is met.
Replay: Automated read-out of live values at a high sampling rate when a trigger condition is met.
2. Usage of MQTT
2.1 Unique Identifier of ePlugs
Every ePlug shall use its Ethernet MAC as a unique identifier where requested. The unique identifier is called UID in this document and shall be represented as 12 hex-digits with letters in uppercase.
Example: UID = 11AA23BC45DE
2.2 Connection settings
The ePlugs communicate with SICON.OS via the MQTT broker that is built into SICON.OS. How plugs can discover the IP-address of the broker is described in Section 4.
Access to the MQTT broker is restricted by a username/password combination. Please contact GPS GmbH to get the credentials required for ePlugs.
Unless otherwise noted, the following settings shall be used by all MQTT clients:
Connections to the broker are started with QoS = 0 and clean Session = true
The keep Alive feature shall be used with the broker with an adequate timeout. This feature allows both broker and client to detect disconnections and react accordingly.
The client id in the MQTT CONNECT message shall be set as follows:
<VendorName>-<UID> with the Vendor Name clipped to a maximum of 10 characters because the client id in MQTT is restricted to a total of 23 characters.
An LWT (last will and testament) is only set in case of the “onCloud” connection method (see 4.2)
All messages are published with retain = false (except for the LWT for onCloud connection)
2.3 General rules for MQTT clients
All MQTT clients should be implemented with a good level of tolerance towards incoming data. In particular:
Messages on unknown or unsupported subtopics shall be ignored without further reaction.
Messages with zero-length payload shall be ignored without further reaction.
Missing or incorrectly specified data in a message: whenever possible, an internal default value for that data shall be used and the message processed anyway. If no reasonable default value can be defined for a required parameter, the message shall be responded to with a “not-acknowledge” or ignored.
When waiting for a certain type of message, there shall be a way to exit this wait condition in case the message never arrives, usually a timeout with fallback to a previous or idle state.
2.4 Topics
All the topics of the eMQTT protocol adhere to the following scheme:
eMQTT/<recipient identifier>/<sender identifier>/<command name>
Using this scheme, the command name can stay the same for request and response. Just the identifiers of sender and recipient swap places.
There are 3 types of identifiers used in this scheme:
The ePlug as a virtual entity, for managing the plug and connecting/disconnecting devices.
CODEIdentifier = <UID>
The sub-interfaces in the ePlug, for exchanging commands and data with their corresponding devices.
CODEIdentifier = <UID>_<SubinterfaceID>
The eMQTT adapter within SICON.OS.
CODEIdentifier = “adapter”
All parts of the topics are written in lowerCamelCase.
Example for the getStatData command:
Request
CODEeMQTT/112233445566_p1/adapter/getStatData
Response
CODEeMQTT/adapter/112233445566_p1/getStatData
2.5 Payloads
Every MQTT payload in the eMQTT protocol contains a JSON object. It can be an empty object “{}” or contains a number of defined JSON keys with their respective values, depending on the command name of the message.
All JSON keys are written in UpperCamelCase with the exception of the timestamp “ms”.
The JSON values are represented as strings, numbers or boolean of the JSON format. In some cases the distinction between string and number (with and without quotation marks) is used to differentiate between valid data and error codes.
2.5.1 HexStrings
All data read from or written to the underlying device is represented as a “HexString”. This means a hexadecimal representation of the data (always 2 characters per byte, letters as upper case) contained within a JSON string. The length of the data is thus implicitly given by the length of the HexString.
When encoding decimals with size > 1 byte, the big-endian representation is used (MSB first).
Examples:
A byte containing the decimal number 100 in HexString format: “64”
2 Bytes containing the 16 bit signed integer - 650 in HexString format: “FD76”
The string “hello” in HexString format: “68656C6C6F”
2.5.2 Timestamps
eMQTT uses a simple type of timestamp: a 48-Bit value that represents the number of milliseconds since 1st Jan 1970, 0:00 AM. (With 48 bits this timestamp will overflow in the year 10871).
During the registration process, the ePlug gets sent the current timestamp of SICON.OS without compensation for network delay. From then on, the plug tracks this timestamp internally and will add it to certain messages as defined in this document.
2.5.3 Error codes
Certain response messages can either contain data or an error code. The list of error codes is based on error codes found in the IO-Link specification as “additional code” values of ISDU responses, but extended by some additional codes.
Code (decimal) | Meaning |
17 | Index not available |
18 | Sub-index not available |
35 | Access denied (index not writable or device is locked etc.) |
48 | Value out of range |
49 | Value greater than limit |
50 | Value less than limit |
51 | Value too long (size of data) |
52 | Value too short (size of data) |
53 | Function not available |
54 | Function temporarily not available |
65 | Parameter set inconsistent |
998 | Request timed out |
999 | General error / unknown cause |
1000 | updateFirmware: Unable to get firmware file |
1001 | updateFirmware: Error during update process |
2.6 Acknowledge messages
Certain commands are defined as requiring an acknowledge (see table in 2.7). The acknowledge message sent for this purpose uses a topic with the same command name as the original request but with sender identifier and recipient identifier swapped (so going in the opposite direction).
<acknowledge> |
| ||
Original topic: | eMQTT/<responder>/<caller>/<command> | ||
Topic: | eMQTT/<caller>/<responder>/<command> | ||
Payload example: | {“Value”:”nak”, “Active”:10,”Max”:10} | ||
Acknowledge? | no | ||
Attribute | Mult | Datatype | Description |
Value | 1 | String | “ack|nak” – positive or negative response to the command |
Active | 0..1 | Number | (optional): number of active channels for the command |
Max | 0..1 | Number | (optional): maximum available number of active channels for the command |
Example for the blink command:
Request:
CODEeMQTT/[UID]/adapter/blink {"Value":"On"}
Acknowledge:
CODEeMQTT/adapter/[UID]/blink {"Value":"Ack"}
Certain commands that can have multiple channels in the same ePlug (such as Observation and Reporting) respond with some additional information about the currently active and maximum amount of channels. So for example if Observation in a given ePlug allows for a maximum of 10 sub-devices to run simultaneously, and an 11th startObservation command is sent, the response will be “nak” with “Active”:10 and “Max”:10, so the caller can react accordingly.
2.7 Overview of all topics with payload examples
Topic | Message Example | Ack? |
Plug Management |
| |
eMQTT/adapter/[UID]/regPlug | {"Address":"192.168.0.1", "ProductName":"SICON.PLUG"} | no |
eMQTT/adapter/[UID]/status | {"Value":"On"} | no |
eMQTT/[UID]/adapter/startPlug | {} | no |
eMQTT/[UID]/adapter/stopPlug | {} | no |
eMQTT/[UID]/adapter/startDevices | {} | no |
eMQTT/[UID]/adapter/blink | {"Value":"On"} | yes |
eMQTT/[UID]/adapter/dateUpdate | {"ms":"0168A8DF825D"} | yes |
Device Management |
| |
eMQTT/adapter/[UID]_[SubinterfaceID]/regDevice | {"Prereg":true,"VendorID":100000, "DeviceID":1, "CyclicDataBitLength":{"PDIn":16, "PDOut":0}, "VendorName":"GPS GmbH", "ProductName":"SICON Example", "ArticleNumber":"10.20.30.40", "SerialNumber":"6543210", "UID":"010100EA018734", "ParentSubinterface":"im1"} | no |
eMQTT/[UID]_[SubinterfaceID]/adapter/regDevice | {"Action":"Abort", "Cause":"Licence"} | no |
eMQTT/adapter/[UID]_[SubinterfaceID]/disDevice | {} | no |
Static Data |
| |
eMQTT/[UID]_[SubinterfaceID]/adapter/getStatData | {"Indices":[16,17,18,20,21]} | no |
eMQTT/adapter/[UID]_[SubinterfaceID]/getStatData | {"16":"475053","17":"546F6C6C65204669726D61", | no |
eMQTT/[UID]_[SubinterfaceID]/adapter/putStatData | {"24":"2A2A2A"} | no |
eMQTT/adapter/[UID]_[SubinterfaceID]/putStatData | {"24":"2A2A2A"} | no |
Cyclic Data |
| |
eMQTT/[UID]_[SubinterfaceID]/adapter/startCyclicData | {"SamplingRate":0} | yes |
eMQTT/[UID]_[SubinterfaceID]/adapter/stopCyclicData | {} | yes |
eMQTT/adapter/[UID]_[SubinterfaceID]/postCyclicData | {"SamplingRate":1000, "ms":"0168A8DF82F3", "PDIn":"2FF7FE816ED3", "PDOut":"49ACD9B4758E"} | no |
eMQTT/adapter/[UID]_[SubinterfaceID]/putCyclicData | {"Value":"0100"} | no |
eMQTT/[UID]_SubinterfaceID]/adapter/putCyclicData | {"Value":35} | no |
Events |
| |
eMQTT/[UID]_[SubinterfaceID]/adapter/startEvents | {} | yes |
eMQTT/[UID]_[SubinterfaceID]/adapter/stopEvents | {} | yes |
eMQTT/adapter/[UID]_[SubinterfaceID]/postEvent | {"ms":"0165D24F660E","Code":1101, "Mode":"Appears","Type":"Warning", "XValues":["00123456","00003344"]} | no |
Reporting |
| |
eMQTT/[UID]_[SubinterfaceID]/adapter/startReporting | {"Component":"ejector1","Type":"Event","Code":"12345", "Mode":"Appears", | yes |
eMQTT/[UID]_[SubinterfaceID]/adapter/stopReporting | {"Component":"ejector1"} | yes |
eMQTT/adapter/[UID]_[SubinterfaceID]/postReport | {"ms":"0165D24F660E", "Component":"ejector1", Values":["01","100000","00342187","02E0","0245","00A4","00B4","02E0","32F4","00EA",...]} | no |
Replay |
| |
eMQTT/[UID]_[SubinterfaceID]/adapter/startReplay | {"Component":"ejector1","Triggers":[{"Code":36002,"Mode":"Singleshot"}, {"Code":6532,"Mode":"Appears"}], "YIndices":[64,65,66,67]} | yes |
eMQTT/[UID]_[SubinterfaceID]/adapter/stopReplay | {"Component":"ejector1"} | yes |
eMQTT/[UID]_[SubinterfaceID]/adapter/triggerReplay | {"Component":"ejector1","Label":"Test cycle 1"} | no |
eMQTT/adapter/[UID]_[SubinterfaceID]/postReplay | {"Component":"ejector1","SamplingRate":10, "ms":"0165D24FF468", "EventCode":6168, "TriggerTimestamp":"0165D24FF500", "LastSegment":false, "Label":"Test cycle 1", "Y1":["07E0","07DE","07E2",...], "Y2":["0023","0023","0021",...]} | no |
Firmware Update |
| |
Variant ESP |
| |
eMQTT/[UID]/adapter/updateFirmware | {"URLFirmwareLocation":"http://192.168.0.1:3232/new_Firmware.bin"} | no |
eMQTT/adapter/[UID]/updateFirmware | {"Status":"InProgress"} | no |
eMQTT/adapter/[UID]/updateFirmware | {"Status":"Ok","Message":"Update successfully completed. Rebooting"} | no |
Note: the column “ACK?” shows whether the message shall be responded to with an acknowledge message as described in 2.6. Other messages do have specific responses, as described further along in this document.
3. Plug Management
There are 2 possible scenarios for registering an ePlug, depending on their network connectivity:
“onSite” registration can be performed if the ePlug is reachable via HTTP from SICON.OS
“onCloud” registration is required if the ePlug is not reachable from SICON.OS (e.g. behind a firewall)
3.1 Registering onSite
When configured for onSite registration, the ePlug waits for a trigger over HTTP to become active.
SICON.OS sets the broker IP to be used by the ePlug via HTTP POST:
POST method to http://<ePlug-IP-address>/set_broker_host
Content-type: application/json
Body: {"MQTT_HOST":<broker-IP-address>} (e.g. {"MQTT_HOST":"192.168.3.110"})
The response of the ePlug shall be the following message:
{"Status":"OK"} or {"Status":"FAIL", "Message":<error message>}
After receiving the HTTP trigger, the ePlug shall respond with the status message (see 3.3) with status “off” within 15 seconds. SICON.OS then reacts with the startPlug message.
Furthermore, the ePlug shall provide the following URL on its HTTP server:
http://<ePlug-IP-address>/status
as this will be polled periodically by SICON.OS to detect connection loss.
3.2 Registering onCloud
The first step to perform onCloud registration is done manually by the user:
Local configuration of the ePlug with the IP-address of SICON.OS (OT-interface)
Following this, the ePlug shall connect to the MQTT broker on the given IP address by setting an LWT (last will and testament message) as follows (see 3.3).
status |
|
Topic: | eMQTT/adapter/[UID]/status |
Payload: | {“Value”:”Disconnected”} |
Retain: | true |
To make its presence known to SICON.OS, the ePlug shall then periodically publish the regPlug message every 5 seconds until SICON.OS reacts with the startPlug message ( ).
regPlug |
| ||
Topic: | eMQTT/adapter/[UID]/regPlug | ||
Payload example: | {“Address”:”192.168.0.1”, “ProductName”:”SICON.PLUG”} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
Address | 1 | String | IP address of the ePlug |
ProductName | 1 | String | SICON.PLUG (same value for all ePlugs) |
To detect connection loss in the case of onCloud registration, SICON.OS keeps listening to the LWT message of the ePlug.
3.3 ePlug status
eMQTT plugs are in one of 2 different connection states and publish their current state using the status message.
status | (requires acknowledge: no) | ||
Topic: | eMQTT/adapter/[UID]/status | ||
Payload example: | {“Value”:”On”} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
Value | 1 | String | “Off|On|Disconnected” |
ProtocolVersion | 0..1 | String | eMQTT Protocol Version (major.minor.patch, e.g. “2.0.0”) |
State | Description |
Off | Initial state after being switched on Devices on sub-interfaces are not registered and no data are sent out |
On | Active state, devices on sub-interfaces are registered and unregistered Data (static, cyclic, events, reporting, replay) are sent out according to requests received |
Disconnected | Used as LWT message for ePlugs that are connected “onCloud” (see 3.1) |
3.4 Starting and stopping plugs
Plugs are in the state “off” upon startup, i.e. they do not register devices. To switch the plug between on and off states, the commands startPlug and stopPlug are used.
startPlug | (retain = false) |
Topic: | eMQTT/[UID]/adapter/startPlug |
Payload: | {} |
Acknowledge? | yes |
stopPlug | (retain = false) |
Topic: | eMQTT/[UID]/adapter/stopPlug |
Payload: | {} |
Acknowledge? | yes |
The plug reacts by publishing its resulting status as described in section 3.3. The stopPlug command does not result in any disDevice messages being sent.
3.5 Starting full registration
When switched from off to on state, the plug shall only pre-register its main device. Only upon receipt of startDevices shall further sub-interfaces be registered.
Also, upon receipt of startDevices, the ePlug shall store the broker-IP non-volatile in EEPROM and only accept HTTP POST requests for this same broker IP. The broker-IP can be reset by a factory-reset command to the ePlug.
startDevices | (retain = false) |
Topic: | eMQTT/[UID]/adapter/startDevices |
Payload: | {} |
Acknowledge? | no |
3.6 Date Update
Certain messages like cyclic data and events require a timestamp and thus all plugs shall receive date information from the mapper before these kind of messages are requested.
The adapter will send a dateUpdate message with the server date in a raw millisecond format of 48-Bit length. This field counts the milliseconds since 1st Jan 1970, 0:00 AM. The plug shall respond with an acknowledge message when the time stamp has been updated.
dateUpdate | (retain = false) | ||
Topic: | eMQTT/[UID]/adapter/dateUpdate | ||
Payload example: | {"ms":"015FE62C8C00"} | ||
Acknowledge? | yes | ||
Attribute | Multiplicity | Datatype | Description |
ms | 1 | String | Timestamp in milliseconds since 1st Jan 1970, 0:00 AM. Formatted as HexString of 12 characters (= 6 byte of data). |
If no dateUpdate message has been received, the plug shall use one of these methods as timestamp:
o If internal real-time clock is available: use own time
o Otherwise: use the time since power-up of the ePlug.
3.7 Identifying Plugs with blink
Plugs that support the “blink”-Feature can be made to flash one or more of their LED's or other display elements in order for the user to identify which device they are currently viewing in SICON.OS.
To make the plug start or stop blinking the following message is defined:
blink | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]/blink | ||
Payload example: | {"Value“:"On"} | ||
Acknowledge? | yes | ||
Attribute | Multiplicity | Datatype | Description |
Value | 1 | String | “On”|”Off” |
The plug shall keep blinking until either “Value”:”Off” is received or the connection to SICON.OS is lost.
4. Device Management
Every plug is subdivided into one or more Sub-interfaces. The Sub-interface IDs are predefined by each particular plug and shall adhere to the following regular expression.
^[a-zA-Z0-9]{1,10}$ (alphanumeric, maximum of 10 characters, case matters).
The root of the sub-interface hierarchy is called “main” and shall always be present.
For IO-Link ports, the Sub-interface IDs are named “p1”, “p2”, “p3” etc. adhering to ^p[1-9]{1}[0-9]{0,2}$.
4.1 Registered and unregistered devices
4.1.1 Registration request
Plugs recognize any devices connected to their sub-interfaces and subscribe them with the command regDevice:
regDevice | (retain = false) | ||
Adapter topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/regDevice | ||
Payload example: | {"VendorID":234, "DeviceID":100610, “CyclicDataBitLength”:{“PDIn”:16, “PDOut”:0}, "VendorName":"J. Schmalz GmbH", "ProductName":"VSi-D", "ArticleNumber":"10.20.30.00123", "SerialNumber":"999000001", “HardwareRevision”:”02”, “FirmwareRevision”:”1.13”, “ParentSubinterface”:”main”, “UID“:“ 010100EA018734“, “Prereg”:true} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
VendorID | 1 | Number | Vendor ID within the respective namespace (IODD or SDD) |
DeviceID | 1 | Number | Device ID |
ParentSubinterface | 0..1 | String | SubinterfaceID of the parent sub-interface in the device’s hierarchy. Default = “main” (if attribute missing) |
Prereg | 0..1 | Boolean | Default = false (if attribute is missing) Set to true, if startDevices has not been received yet |
CyclicDataBitLength | 1 | Object | Lengths of cyclic data of connected device |
CyclicDataBitLength::PDIn | 1 | Number | 0 if no input process data |
CyclicDataBitLength::PDOut | 1 | Number | 0 if no output process data |
VendorName | 0..1 | String |
|
ProductName | 0..1 | String |
|
ArticleNumber | 0..1 | String |
|
SerialNumber | 0..1 | String |
|
UID | 0..1 | HexString | Unique ID of the device,if available |
4.1.2 Registration response
When the adapter recognizes the device and continues registration, there is no direct response to regDevice. The adapter will start reading device data via getStatData calls.
It is however possible that registration is temporarily or permanently disabled for a certain sub-interface (e.g. by choice of the user). In this case, the adapter shall inform the plug that registration will not resume (yet) by sending a regDevice response:
regDevice | (retain = false) | ||
Adapter topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/regDevice | ||
Payload example: | {"Action":“Abort”, “Cause”:“Licence“} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
Action | 1 | String | Possible values: “Abort” |
Cause | 0..1 | String | Possible values: “Licence” |
For plugs that can have several sub-interfaces and register them sequentially, this message shall cause the plug to skip to registration of the next available and unregistered sub-interface.
4.1.3 Un-registration request
If a device gets disconnected from the interface of the plug, the plug sends a disDevice message:
disDevice | (retain = false) |
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/disDevice |
Payload: | {} |
Acknowledge? | no |
The disconnection of a device shall cause all active processes (like sending events or reports) and states (like sending events when they occur) to be reset to their default / idle states.
4. Static Data
Static data are accessible as acyclic parameters in the IOT devices and generally represent data with a low rate of change. Typically this includes identification data and device settings. Static data are referenced by a numerical index (without sub-index) and always represented as HexStrings.
4.1 Reading Static Data
4.1.1 Read Request
getStatData | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/getStatData | ||
Payload example: | {"Indices”:[13, 14, 15, 16]} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
Indices | 1 | Array[1..5] of Number | Array of numbers giving the indices to be read, up to a maximum of 5 indices per message. |
Restrictions: only 1 such request shall be pending across all sub-interfaces of a plug and only up to 5 indices may be present in the request.
4.1.2 Read Response
getStatData | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/getStatData | ||
Payload example: | {“13”:”AABBCCDD010203”, “14”:“102030405060”, “15”:17, “16”:35} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
<Index>:<Value> | 1..5 | String or Number | 1 key-value pair for every requested index Value contains the data that was written as a HexString or an error code as a number |
The ePlug may send the responses distributed over several getStatData responses. E.g. a request for 5 indices may be answered in 1, 2, 3, 4 or 5 separate messages.
In case of a successful read, the data for each index is transmitted as a HexString. In case of error, an error code is transmitted as a JSON number. The error codes are defines in section 2.5.3.
4.2 Writing static data
4.2.1 Write Request
putStatData | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/putStatData | ||
Payload example: | {“100“:”00FD”} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
<Index>:<Value> | 1 | String | <Index> gives Index <Value> is the data to be written as HexString |
4.2.2 Write Response
putStatData | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/putStatData | ||
Payload example: | {"100“:49} or {“100”:”00FD”} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
<Index>:<Response> | 1 | String or Number | <Index> gives Index <value> is the data that was written as a HexString or an error code as a number |
In response, the plug shall transmit either an error code as a number or echo the value that was written as a HexString. The error codes are defines in section 2.5.3.
4.2.3 Device-specific commands
In the eMQTT protocol, device commands like “Reset to factory defaults”, “Sensor calibration”, “Teach-In” etc. are handled like System Command in IO-Link. That means they are sent as a 1 byte write-request to Index 2 using putStatData.
5. Cyclic Data
5.1 Observing Cyclic Data
Cyclic data is periodically transmitted data that usually corresponds to a device’s process data.
Cyclic data for a sub-interface consists of up to 2 separate channels:
The input process data channel is called “PDIn” and contains the data flowing from the field device to the controller, e.g. sensor values, threshold bits etc.
The output process data channel is called “PDOut” and contains the data flowing from the controller to the field device, e.g. actor control, target values etc.
5.1.1 Request
The cyclic data can only be requested in their entirety with a fixed sampling rate
startCyclicData | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/startCyclicData | ||
Payload example: | {"SamplingRate":0} | ||
Acknowledge? | yes | ||
Attribute | Multiplicity | Datatype | Description |
SamplingRate | 1 | Number | Time in ms between 2 samples. Default: 0 If 0, the plug shall use its internally defined minimum sampling rate. |
stopCyclicData | (retain = false) |
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/stopCyclicData |
Payload: | {} |
Acknowledge? | yes |
5.1.2 Response
In response, the ePlug shall send out messages of this type periodically:
postCyclicData | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/postCyclicData | ||
Payload example: | {"SamplingRate":1000, “ms”:”0165D24FF468”, “PDIn”:“80000000”, “PDOut”:“01”} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
SamplingRate | 1 | Number | The actual sampling rate that the plug is using |
ms | 1 | String | Timestamp of the first sample in the data array (in HexString format) |
PDIn | 1 | String | HexString containing the input cyclic data. Empty string if no input data are defined. |
PDOut | 1 | String | HexString containing the output cyclic data. Empty string if no output data are defined. |
Remarks on SamplingRate:
A sampling rate of 0 causes the plug to use its internally defined default sampling rate, typically 1000 ms.
A sampling rate smaller than the plug’s minimum sampling rate (but != 0) causes the plug to use its internally defined minimum sampling rate.
Because the actually used sampling rate can thus differ from what was requested, the plug shall include the actual sampling rate in the post Cyclic Data message.
5.2 Forcing output process data
For plugs that allow this capability, the output process data of the device can be forced by the following message:
putCyclicData | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/putCyclicData | ||
Payload example: | {“Value”:”0100”} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
Value | 1 | String | New output process data as HexString, must correspond to the output bitlength of the device |
In eMQTT the process data cannot be forced partially, only in their entirety.
The ePlug shall respond with a mirror of the output data or an error code:
putCyclicData | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/putCyclicData | ||
Payload example: | {“Value”:”0100”} or {“Value”:35} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
Value | 1 | String or Number | data that was written as a HexString or an error code as a number |
7. Events
7.1 Starting & stopping events
The sending of events can be switched on or off with these messages:
startEvents | (retain = false) |
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/startEvents |
Payload: | {} |
Acknowledge? | yes |
stopEvents | (retain = false) |
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/stopEvents |
Payload: | {} |
Acknowledge? | yes |
7.2 Sending events
Once events have been started, the plug shall send a postEvent message for each event that occurs in the device.
postEvent | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/postEvent | ||
Payload example: | {"ms":"123456789AB","Code":16, "Mode":"Disappears" "Notice":"Index, 270mbar/350mbar"} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
ms | 1 | String | Timestamp in ISO format |
Code | 1 | Number | Event code |
Mode | 1 | String | "Appears|Disappears|Singleshot" |
Type | 0..1 | String | “Notification|Warning|Error” (can be omitted if the type is not known to the plug) |
Notice Notice: { “reg”: “^(\d+)/(\d+)$”, “trans”: “You reached $1 mbar of max. $2 mbar” } | 0..1 | String | Free text with further detailed information |
Note: Similar to the IO-Link specification, the event type dictates which event modes can occur:
Events of type “Notification” can only have mode “Singleshot”
Events of type “Warning” or “Error” can only have modes “Appears” or “Disappears”
8. Reporting
The Reporting mechanism allows for the transmission of a requested set of static data items when a certain trigger condition is met.
After receiving the startReporting message, the plug shall monitor the trigger condition and automatically read the requested static data from the device and send it out over MQTT. There is only 1 trigger active in a sub-interface & component combination at any given time and the reception of a new startReporting message shall cancel and overwrite the old trigger.
8.1 Triggers
There are several different trigger mechanisms to define when the Reporting data are to be sent:
Time-based trigger (“Type”:”Time”): The first Reporting is done right after receipt of startReporting and updates are sent periodically thereafter.
“SamplingRate”:<time in ms> - Update rate of the reports
Event-based trigger (“Type”:”Event”): Waits for the occurrence of a specific device event. Whenever the specified event code is received with the specified incidence, the Reporting data shall be sent.
“Code”:<event_code> - decimal coded event number (as in section 8.2)
“Mode”:”Singleshot|Appears|Disappears” – event incidence mode, see section 8.2. So the trigger could be defined to react on a disappearing event as well.
Self-triggered (“Type”:”Self-triggered”): In this case the plug has certain application knowledge built-in and reacts to an internal condition that shall trigger the Reporting data.
The plug is not required to implement all trigger-types.
8.2 Starting reporting
Setting up the trigger condition:
startReporting | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/startReporting | ||
Payload example: | {"Component":"ejector1","Type":"Event","Code":"12345", "Mode":"Appears", | ||
Acknowledge? | yes | ||
Attribute | Multiplicity | Datatype | Description |
Component | 1 | String | Component name |
Type | 1 | String | “Time|Event|Self-triggered” |
SamplingRate | 0..1 | Number | Present if and only if Type equals “Time” |
Code | 0..1 | Number | Event code, present if and only if Type equals “Event” |
Mode | 0..1 | String | Event incidence: “Appears|Disappears|Singleshot” Present if and only if Type equals “Event” |
Indices | 1 | Array[1..30] of Number | List of static data indices that shall be sent as Values. |
If the requested trigger-type is not supported, the plug will send a NACK response.
Reporting for a given sub-interface can be stopped again by the following message:
stopReporting | (retain = false) |
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/stopReporting |
Payload: | {"Component":"ejector1"} |
Acknowledge? | yes |
8.3 Sending the report
postReport | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/postReport | ||
Payload example: | {"ms":"0165D24F660E","Component":"ejector1",], "Values":["01","100000","00342187","02E0","0245","00A4", "00B4","02E0","32F4","00EA"]} | ||
Acknowledge? | no | ||
Attribute | Multiplicity | Datatype | Description |
ms | 1 | String | Timestamp in ms-coded HexString Format |
Component | 1 | String | Component name |
Values | 1 | Array[1..30] of Number | Array of up to 30 data entries for the requested Indices in the same order as requested |
9. Replay
The Replay feature allows for a certain set of device data to be monitored retroactively when a given condition occurs. For this, the plug provides an internal FIFO or “rolling buffer” that can store an amount of samples for up to 30 indices. The FIFO is constantly updated at a given sampling rate after the startReplay message has been received.
The FIFO is structured as a pre-event section and a post-event section. That means, that the plug shall continue sampling after the event has occurred, until the length of the post-event section has also been filled. Then the plug shall send the contents of the whole FIFO, thus giving the user data from both before and after the event.
The sampling rate, size of the FIFO as well as the lengths of pre-event and post-event sections are set to fixed values internally in the plug.
More than one event can be set as a trigger condition, these conditions shall be observed by the plug simultaneously (logic OR).
9.1 Starting Replay
startReplay | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/startReplay | ||
Payload example: | {"Component":"ejector1","Triggers":[{"Code":36002,"Mode":"Singleshot"}, {"Code":6532,"Mode":"Appears"}], "Indices":[64,65,66,67]} | ||
Attribute | Multiplicity | Datatype | Description |
Component | 1 | String | Component name |
Triggers | 1 | Array of Object | a list of all the event triggers that shall be observed by the plug |
Triggers:Code | 1 | Number | Event code
|
Triggers:Mode | 1 | String | Event incidence: “Appears|Disappears|Singleshot” |
Indices | 1 | Array[1...30] of Number | List of static data indices that shall be sent as n-values. |
Replay for a given sub-interface can be stopped again by the following message:
stopReplay | (retain = false) |
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/stopReplay |
Payload: | {"Component":"ejector1"} |
Acknowledge? | yes |
9.2 Manual replay trigger
To allow for manual control of the replay feature, a "user trigger" event is defined with code 36002 and type "Notification". It can be triggered by the following message:
triggerReplay | (retain = false) | ||
Topic: | eMQTT/[UID]_[SubinterfaceID]/adapter/triggerReplay | ||
Payload example: | {"Component":"ejector1","Label":"Test cycle 1"} | ||
Attribute | Multiplicity | Datatype | Description |
Component | 1 | String | Component name |
Label | 1 | String | This label shall be stored by the plug an added to every postReplay message |
When the plug receives this message, it shall generate the "user trigger" event, trigger a replay and also send a postEvent message for the event.
9.3 Sending Replay
The replay data is sent out using one or more postReplay messages. If the FIFO cannot be sent completely in 1 message, the plug shall segment it over several messages, each with the exact same "TriggerTimestamp". The TriggerTimestamp must also match the postEvent message of the triggering event for this replay. It is used at the recipient's end to correlate the event and all the replay segments.
postReplay | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]_[SubinterfaceID]/postReplay | ||
Payload example: | {"SamplingRate":10, "ms":"0165D24FF468", "Component":"ejector1", "EventCode":6168, “TriggerTimestamp”:”0165D24FF500”, "LastSegment":true, "Label":"Test cycle 1", "Values":" [["07E0","07DE","07E2",...], ["0023","0023","0021",...],...]} | ||
Attribute | Multiplicity | Datatype | Description |
Component | 1 | String | Component name |
SamplingRate | 1 | Number | The sampling rate used, i.e. temporal distance of the values in the arrays |
ms | 1 | String | Timestamp of the first sample of this segment (in HexString format) |
EventCode | 1 | Number | Event code of the event that triggered the replay |
TriggerTimestamp | 1 | String | Timestamp of when the trigger for the replay has occured. This must be an exact match for every segment and for the corresponding postEvent message. |
LastSegment | 0..1 | Boolean | Signal that this is the last segment for the ongoing replay. No further segments will be sent. default = false |
Label | 0..1 | String | If the replay was triggered by the "user trigger" event, the Label from the triggerReplay message shall be copied here for each segment |
Values | 1 | Array of Array of String | An array of array of data samples for every member of Indices of the startReplay message. Arrays of data must have the same length. The data are given as HexStrings |
Each segment message gives a number of samples for every index. The first sample in each array is the one that occurred at the time of the "ms"-Timestamp while the remaining samples are each a period of the length of the SamplingRate apart. The "TriggerTimestamp" is used as a reference point, to regroup the segments of the same replay. Also it is used to match it to the triggering postEvent-message.
10. Firmware Update
Different methods for initiating a firmware update of the ePlug will be implemented, depending on the requirements of the underlying devices.
10.1 Firmware Update for ESP-Plugs
Initiating a firmware update:
updateFirmware | (retain = false) | ||
Topic: | eMQTT/[UID]/adapter/updateFirmware | ||
Payload example: | {"URLFirmwareLocation": "http://192.168.0.1:3232/new_Firmware.bin"} | ||
Attribute | Multiplicity | Datatype | Description |
URLFirmwareLocation | 1 | String | URL of the new firmware file |
The ePlug will fetch the firmware file from the given URL and respond with the following types of messages:
updateFirmware | (retain = false) | ||
Topic: | eMQTT/adapter/[UID]/updateFirmware | ||
Payload example: | {"Status":"InProgress"} or {"Status":"Ok","ErrorCode":4512} | ||
Attribute | Multiplicity | Datatype | Description |
Status | 1 | String | InProgress|Ok|Fail |
ErrorCode | 0..1 | String | Error code in case of “Fail” |
11. Example MQTT log
In the following, an example MQTT log of device registration and normal operation is provided to clarify the use of the various eMQTT messages.
HTTP-Trigger has been set, ePlug reacts on MQTT:
eMQTT/adapter/00301133E40F/status : {"Value":"Off" }
1. The adapter triggers preregistration:
eMQTT/00301133E40F/adapter/startPlug : {}
eMQTT/adapter/00301133E40F/status : {"Value":"On" }
eMQTT/adapter/00301133E40F_main/regDevice : {"DeviceID":34728,"VendorID":200234,"Prereg":true,"CyclicDataBitLength":{"PDIn":0,"PDOut":0},"VendorName":"J. Schmalz GmbH","ProductName":"SCTSi-PNT","SerialNumber":"305419896","ArticleNumber":"10.02.99.10502","UID":"00301133E40F"}
2. The adapter triggers full registration:
eMQTT/00301133E40F/adapter/startDevices : {}
3. The ePlug has to register the main-device first:
eMQTT/adapter/00301133E40F_main/regDevice : {"DeviceID":34728,"VendorID":200234,"CyclicDataBitLength":{"PDIn":0,"PDOut":0},"VendorName":"J. Schmalz GmbH","ProductName":"SCTSi-PNT","SerialNumber":"305419896","ArticleNumber":"10.02.99.10502","UID":"00301133E40F"}
eMQTT/00301133E40F_main/adapter/getStatData : {"Indices":[16,18,20,21,22]}
eMQTT/adapter/00301133E40F_main/getStatData : {"16":"4A2E205363686D616C7A20476D6248" }
eMQTT/adapter/00301133E40F_main/getStatData : {"18":"53435453692D504E54" }
eMQTT/adapter/00301133E40F_main/getStatData : {"20":"53435453692D4142432D34343434343434342D34343434343434342D502D303030303030302D56493030" }
eMQTT/adapter/00301133E40F_main/getStatData : {"21":"333035343139383936" }
eMQTT/adapter/00301133E40F_main/getStatData : {"22":"362E31" }
eMQTT/00301133E40F_main/adapter/getStatData : {"Indices":[23,24,36,90,91]}
eMQTT/adapter/00301133E40F_main/getStatData : {"23":"322E332E35" }
eMQTT/adapter/00301133E40F_main/getStatData : {"24":"2A2A2A" }
eMQTT/adapter/00301133E40F_main/getStatData : {"36":"00" }
eMQTT/adapter/00301133E40F_main/getStatData : {"90":"00" }
eMQTT/adapter/00301133E40F_main/getStatData : {"91":"0000" }
eMQTT/00301133E40F_main/adapter/getStatData : {"Indices":[138]}
eMQTT/adapter/00301133E40F_main/getStatData : {"138":"00100000" }
eMQTT/00301133E40F/adapter/dateUpdate : {"ms":"0171DE2AD379"}
eMQTT/adapter/00301133E40F/dateUpdate : {"Value":"Ack" }
eMQTT/00301133E40F_main/adapter/startEvents : {}
eMQTT/adapter/00301133E40F_main/startEvents : {"Value":"Ack" }
4. The ePlug registers its other Sub-devices, making sure that parent sub-interfaces get registered before their children (im1 before im1p3 in this case):
eMQTT/adapter/00301133E40F_im1/regDevice : {"DeviceID":3,"VendorID":100001,"CyclicDataBitLength":{"PDIn":0,"PDOut":0},"VendorName":"J. Schmalz GmbH","ProductName":"SCTSi-IOLM","SerialNumber":"1 ,eMQTT/","ArticleNumber":"2 ,eMQTT/0030","UID":"0102000186A10000000300FD354F"}
eMQTT/00301133E40F_im1/adapter/getStatData : {"Indices":[16,18,19,21,22]}
eMQTT/adapter/00301133E40F_im1/getStatData : {"16":"4A2E205363686D616C7A20476D6248" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"18":"53435453692D494F4C4D" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"19":"433638" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"21":"3100002C654D5154542F" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"22":"3032" }
eMQTT/00301133E40F_im1/adapter/getStatData : {"Indices":[23,36,240,250,251]}
eMQTT/adapter/00301133E40F_im1/getStatData : {"23":"56312E312E32" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"36":"00" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"240":"0102000186A10000000300FD354F" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"250":"3200002C654D5154542F30303330" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"251":"3000" }
eMQTT/00301133E40F_im1/adapter/getStatData : {"Indices":[252,10404,138]}
eMQTT/adapter/00301133E40F_im1/getStatData : {"252":"44313900000000000000" }
eMQTT/adapter/00301133E40F_im1/getStatData : {"10404":"04040404"}
eMQTT/adapter/00301133E40F_im1/getStatData : {"138":"100000" }
eMQTT/00301133E40F/adapter/dateUpdate : {"ms":"0171DE2ADA75"}
eMQTT/adapter/00301133E40F/dateUpdate : {"Value":"Ack" }
eMQTT/00301133E40F_im1/adapter/startEvents : {}
eMQTT/adapter/00301133E40F_im1/startEvents : {"Value":"Ack" }
5. Now im1p3, a sub-device of im1 can be registered:
eMQTT/adapter/00301133E40F_im1p3/regDevice : {"DeviceID":100213,"VendorID":234,"CyclicDataBitLength":{"PDIn":32,"PDOut":16},"VendorName":"J. Schmalz GmbH","ProductName":"SXPi_SXMPi_PC_V2","SerialNumber":"000000001","ArticleNumber":"10.02.02.05307","UID":"0A020205030202003C008200EA01877500000001","ParentSubinterface":"im1"}
eMQTT/00301133E40F_im1p3/adapter/getStatData : {"Indices":[16,17,18,19,20]}
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"16":"4A2E205363686D616C7A20476D6248" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"17":"7777772E7363686D616C7A2E636F6D" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"18":"535850695F53584D50695F50435F5632" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"19":"535850695F53584D50695F50435F5632" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"20":"53585069203235204E4320" }
eMQTT/00301133E40F_im1p3/adapter/getStatData : {"Indices":[21,22,23,24,32]}
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"21":"303030303030303031" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"22":"3038" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"23":"322E3136" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"24":"3132333435363738393031323334353637383930313233343536373839303939" }
eMQTT/adapter/00301133E40F_im1p3/getStatData : {"32":"0001" }
eMQTT/00301133E40F/adapter/dateUpdate : {"ms":"0171DE2B53BC"}
eMQTT/adapter/00301133E40F/dateUpdate : {"Value":"Ack" }
eMQTT/00301133E40F_im1p3/adapter/startCyclicData : {"SamplingRate":0}
eMQTT/00301133E40F_im1p3/adapter/setXConfig : {"XIndices":[140,0,0,0],"AutomaticReadForEvents":false,"AutomaticReadForReporting":false}
eMQTT/adapter/00301133E40F_im1p3/startCyclicData : {"Value":"Ack" }
eMQTT/adapter/00301133E40F_im1p3/setXConfig : {"Value":"Ack" }
eMQTT/00301133E40F_im1p3/adapter/startEvents : {}
eMQTT/adapter/00301133E40F_im1p3/startEvents : {"Value":"Ack" }
eMQTT/00301133E40F_im1p3/adapter/stopReporting : {}
eMQTT/00301133E40F_im1p3/adapter/startReporting : {"Type":"Event","Indices":[16100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Code":6168,"Mode":"Singleshot"}
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B57F7","SamplingRate":0,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_im1p3/stopReporting : {"Value":"Ack","Active":0,"Max":16 }
Remark: im1p3 will be using only 1 ISDU for reporting, i.e. 16100 (XConfig AutomaticReadForReporting = false). It will be triggered by event Notification 6168.
6. Registration of ej1 is next, which will be using different settings for XConfig and Reporting, making use of a self-trigger:
eMQTT/adapter/00301133E40F_ej1/regDevice : {"DeviceID":1,"VendorID":100001,"CyclicDataBitLength":{"PDIn":8,"PDOut":8},"VendorName":"J. Schmalz GmbH","ProductName":"SCPSt","SerialNumber":"001799787","ArticleNumber":"10.02.02.04679","UID":"0102000186A100000001001B766B"}
eMQTT/adapter/00301133E40F_im1p3/startReporting : {"Value":"Ack","Active":1,"Max":16 }
eMQTT/00301133E40F_ej1/adapter/getStatData : {"Indices":[12,16,18,19,21]}
eMQTT/adapter/00301133E40F_ej1/getStatData : {"12":"00" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"16":"4A2E205363686D616C7A20476D6248" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"18":"5343505374" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"19": 17 }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"21":"303031373939373837" }
eMQTT/00301133E40F_ej1/adapter/getStatData : {"Indices":[23,36,100,101,102]}
eMQTT/adapter/00301133E40F_ej1/getStatData : {"23":"312E39" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"36":"00" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"100":"02EE" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"101":"0096" }
eMQTT/adapter/00301133E40F_ej1/getStatData : {"102":"0226" }
eMQTT/00301133E40F/adapter/dateUpdate : {"ms":"0171DE2B6162"}
eMQTT/adapter/00301133E40F/dateUpdate : {"Value":"Ack" }
eMQTT/00301133E40F_ej1/adapter/startCyclicData : {"SamplingRate":0}
eMQTT/adapter/00301133E40F_ej1/startCyclicData : {"Value":"Ack" }
eMQTT/00301133E40F_ej1/adapter/setXConfig : {"XIndices":[140,143,0,0],"AutomaticReadForEvents":true,"AutomaticReadForReporting":true}
eMQTT/00301133E40F_ej1/adapter/startEvents : {}
eMQTT/00301133E40F_ej1/adapter/stopReporting : {}
eMQTT/00301133E40F_ej1/adapter/startReporting : {"Type":"Self-triggered","Indices":[148,149,156,160,161,162,163,164,0,0,0,0,0,0,0,0,0,0,0,0]}
eMQTT/adapter/00301133E40F_ej1/setXConfig : {"Value":"Ack" }
eMQTT/adapter/00301133E40F_ej1/startEvents : {"Value":"Ack" }
eMQTT/adapter/00301133E40F_ej1/stopReporting : {"Value":"Ack","Active":1,"Max":16 }
eMQTT/adapter/00301133E40F_ej1/startReporting : {"Value":"Ack","Active":2,"Max":16 }
7. All Sub-devices are fully registered and normal operation begins:
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B69A3","SamplingRate":1000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B6D8C","SamplingRate":2000,"PDIn":"00","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B7175","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/00301133E40F_main/adapter/getStatData : {"Indices":[36]}
eMQTT/adapter/00301133E40F_main/getStatData : {"36":"00" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B755E","SamplingRate":2000,"PDIn":"00","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B7947","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B7D30","SamplingRate":2000,"PDIn":"00","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B8119","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
8. The user opens im1p3 on the frontend and thus an observation channel is established:
eMQTT/00301133E40F_im1p3/adapter/startObservation : {"SamplingRate":1000,"Indices":[148,161,564,140,165,164,160,147,149,143,145,144,141,142,40,41,67]}
eMQTT/adapter/00301133E40F_im1p3/startObservation : {"Value":"Ack","Active":1,"Max":5 }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B8462","SamplingRate":2000,"PDIn":"00","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B85AE","148":"0000" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B884D","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B8998","161":"0000" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B8C3B","SamplingRate":2000,"PDIn":"00","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B8D86","564":"11" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B902C","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B9177","140":"00013B00" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B941A","SamplingRate":2000,"PDIn":"00","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B95A8","165":"0000" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B980F","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B995A","164":"0000" }
9. The self-trigger in ej1 has been activated by the application and it sends its report:
eMQTT/adapter/00301133E40F_ej1/postReport : {"ms":"0171DE2B9AA8","XValues":["00007200","00007200"],"YValues":["0000","0000","0000","0000","0000","64","64","0001"] }
eMQTT/00301133E40F_main/adapter/getStatData : {"Indices":[36]}
eMQTT/adapter/00301133E40F_main/getStatData : {"36":"00" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2B9BFB","SamplingRate":2000,"PDIn":"00","PDOut":"01" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2B9D46","160":"0000" }
eMQTT/adapter/00301133E40F_ej1/postEvent : {"ms":"0171DE2B9E9F","Type":"Warning","Mode":"Appears","Code": 6154,"XValues":["00007200","00007200"] }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2B9FE9","SamplingRate":2000,"PDIn":"80000002","PDOut":"0200" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2BA134","147":"00" }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2BA3DC","SamplingRate":2000,"PDIn":"20","PDOut":"00" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2BA569","149":"0000" }
eMQTT/adapter/00301133E40F_ej1/postReport : {"ms":"0171DE2BA663","XValues":["00007201","00007201"],"YValues":["03D5","0000","0022","0000","0000","64","64","0001"] }
eMQTT/adapter/00301133E40F_ej1/postEvent : {"ms":"0171DE2BA67E","Type":"Warning","Mode":"Disappears","Code": 6154,"XValues":["00007201","00007201"] }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2BA7CC","SamplingRate":2000,"PDIn":"80000002","PDOut":"0100" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2BA894","143":"0001941A" }
10. For im1p3 the reporting trigger is event-based and the respective event now occurs and triggers a report:
eMQTT/adapter/00301133E40F_im1p3/postEvent : {"ms":"0171DE2BAA1A","Type":"Notification","Mode":"Singleshot","Code": 6168 }
eMQTT/adapter/00301133E40F_im1p3/postReport : {"ms":"0171DE2BAB65","YValues":["00013B0100003CF10001A6F50000000050018800000000000000000000000000"] }
eMQTT/adapter/00301133E40F_ej1/postEvent : {"ms":"0171DE2BAA1A","Type":"Warning","Mode":"Appears","Code": 6154,"XValues":["00007202","00007202"] }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2BABBB","SamplingRate":2000,"PDIn":"20","PDOut":"02" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2BAD06","145":"0001A8EA" }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2BAFB0","SamplingRate":2000,"PDIn":"80000002","PDOut":"0000" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2BB0FC","144":"0001A46A" }
eMQTT/adapter/00301133E40F_ej1/postReport : {"ms":"0171DE2BB21E","XValues":["00007202","00007202"],"YValues":["03D4","0000","0022","0000","0000","64","64","0001"] }
eMQTT/adapter/00301133E40F_ej1/postEvent : {"ms":"0171DE2BB22A","Type":"Warning","Mode":"Disappears","Code": 6154,"XValues":["00007202","00007202"] }
eMQTT/adapter/00301133E40F_ej1/postCyclicData : {"ms":"0171DE2BB39D","SamplingRate":2000,"PDIn":"00","PDOut":"01" }
eMQTT/adapter/00301133E40F_im1p3/postObservation : {"ms":"0171DE2BB52B","141":"00003CF3" }
eMQTT/adapter/00301133E40F_im1p3/postEvent : {"ms":"0171DE2BB5F3","Type":"Notification","Mode":"Singleshot","Code": 6168 }
eMQTT/adapter/00301133E40F_im1p3/postReport : {"ms":"0171DE2BB73E","YValues":["00013B0200003CF20001A6F74200000005018800000000000000000000000000"] }
eMQTT/adapter/00301133E40F_ej1/postEvent : {"ms":"0171DE2BB5F3","Type":"Warning","Mode":"Appears","Code": 6154,"XValues":["00007203","00007203"] }
eMQTT/adapter/00301133E40F_im1p3/postCyclicData : {"ms":"0171DE2BB7A3","SamplingRate":2000,"PDIn":"80000002","PDOut":"0200" }
12. Document revision
05.02.2019 | First document |
05.02.2019 | v0.3 – added putPDout description |
05.02.2019 | v0.4 – declared the “statDataUpdater” feature as “unused” for now |
04.12.2019 | v0.7 – added the “blink” feature and corrected “dateUpdate” in the topic-overview |
10.03.2020 | v0.8 – extension of regPlug message with ProductName |
11.03.2020 | v0.9 – document review and corrections so it matches SICON.OS r0.11.6 |
11.03.2020 | v0.9.1 – Corrections after peer review. Added clickable chapter references. |
11.03.2020 | v0.9.2 – correction of onCloud registration |
24.03.2020 | v0.10.0 – major revamp and inclusion of the Replay feature |
27.03.2020 | v0.10.1 – Added error codes for updateFirmware. Some corrections. |
01.04.2020 | v0.10.2 – Changed “keys” to “Indices” in JSON payloads |
03.04.2020 | v0.10.3 – Changed setXKeys to setXConfig (including new attributes), Changed postCyclicData to names “PDIn”, “PDOut” and to include “Observe |
06.04.2020 | v0.10.4 – changed CyclicDataBitLength in regDevice to “PDIn”,”PDOut”,”Observe”. Change of CM/TM/PM/EM indices/values to just YIndices and YValues. |
07.04.2020 | v0.10.5 – corrected some typos |
15.04.2020 | v0.11.0 – Removed “Observe” from cyclic data and accordingly removed “Observe” from regDeviceCyclicDataBitLength. Created a new group of messages for observation. |
15.04.2020 | v0.11.1 – included missing stop-messages for cyclic data and observation |
28.04.2020 | v0.11.2 – Extended the acknowledge message with optional attributes “Active” and “Max. Extended the regDevice message with “UID” |
28.04.2020 | v1.0.0 – Official first release |
04.05.2020 | v1.0.1 – Added section “Example MQTT log”. Corrected some spelling errors. |
04.05.2020 | v1.0.2 – corrected array sizes in postReport |
13.05.2020 | v1.0.3 - Added UID to regDevice message in topic overview |
25.05.2020 | v1.0.4 – Updated Replay feature. Corrected some typos |
09.06.2020 | v1.0.5 – Replay: added EventCode to postReplay. Corrected Replay messages in topic overview |
16.06.2020 | v1.0.6 – Added description of stopReplay and spotEvents, adapted chapter structure for reporting. In postReplay, removed the requirement for exact match between TriggerTimestamp and postEvent timestamp. |
16.06.2020 | v1.0.7 – In postReplay, the requirement for exact match of replay and event timestamps was put back in, after discussion in the team. |
19.11.2020 | v1.0.8 – Added response message to regDevice to abort registration or otherwise inform the plug |
14.07.2025 | v1.0.9 - Changes for Components needs to only work for SICON.OS version 2024.x |