This page includes examples of the most common Lucid Protocol messages along with a description of the content of each message. You’ll see a text description and then the JSON (JavaScript Object Notation) snippet that is the actual Lucid Protocol packet for that example.
Examples 1 to 9 relate to a simple field device and the messages it may send out within a day. The device has a single digital input connected to a float switch and a single analogue input connected to a level sensor.
Whenever the float switch changes, the device sends that information to the broker. The analogue input is scaled from 0 to 100% and whenever its value drops below 10% it also contacts the broker.
During the day, the value of the analogue input is collected and stored every 10 minutes. The device contacts the broker on a scheduled connection once per day. At that time the device sends all of the stored 10-minute analogue values that have not been previously sent due to a state change of the digital or analogue inputs.
When the device starts up, it will send to the broker:
The example message in this section is the configuration message of our example device. The message contains the configuration of the scheduled connections, the digital point and the analogue point.
{
"cVer": 123,
"full": true,
"device": [
{
"nid": "RES01",
"loc": "Ambleside",
"ownr": "WR",
"asst": "ASST123",
"name": "Ambleside Main Tank",
"serl": "1234567",
"scan": true
}
],
"channel": [
{
"num": 1,
"name": "Main IP Channel",
"conn": "O2",
}
],
"connection": [
{
"num": 1,
"name": "Broker 1",
"channel": 1,
"prot": 1,
"type": 1,
"net": "123.456.789.012:20100",
"retries": 2,
"backoff": 120
}
],
"connectionSchedule": [
{
"num": 1,
"mode": 2,
"start": 0,
"repeat": 86400000
}
],
"deviceLink": [
{
"num": 1,
"name": "Onboard IO"
}
],
"point": [
{
"deviceLink": 1,
"num": 0,
"type": "bi",
"name": "Float Switch",
"className": "Switch",
"scan": true,
},
{
"deviceLink": 1,
"num": 0,
"type": "ai",
"name": "Tank Level",
"className": "Level",
"scan": true,
"logRate": 600000,
"logOffset": 0
}
],
"analogue": [
{
"parent": 0,
"parentType": "ai",
"rawsc1": 0,
"rawsc2": 32768,
"engsc1": 0.0,
"engsc2": 100.0,
"min": 0.0,
"max": 100.0,
"units": "%",
}
],
"binary": [
{
"parent": 0,
"parentType": "bi",
"bits": 1,
"state0Action": 2,
"state0Pers": 60000,
"state1Action": 2,
"state1Pers": 1000
}
],
"analogueLimit": [
{
"parent": 0,
"parentType": "ai",
"num": 0,
"name": "Low",
"action": 2,
"dirctn": 1,
"value": 10.0,
"hyst": 1.0,
"enter": 10000,
}
],
}
A status message is sent to the broker evey time the device connects. It contains:
Note that the identity of the device is not included because that is in the topic to which this message is published. As an example, that topic might be:
0aabbbfa-e241-460e-b702-c6c9559a7c2c/UP/status
Where the UUID at the start of the topic is that of the Field Device.
{
"pRef": "ACME_Device1_1-00",
"cVer": 123,
"time": 1728590330263
}
When the float switch connected to the example device changes, its digital state causes and event to be created and contact to the broker to be initiated. The message below is an example of the data message that includes the current values and the state change of the digital point.
The reason field “r” shows 1 for the current value and 3 for the state change event.
{
"p":
[
{
"ai": 0,
"v": [12],
"q": [0],
"ts": [1728590431263],
"r": [1]
},
{
"bi": 0,
"v": [1, 1],
"ts": [1728590431263, 1728590430263],
"r": [1, 3]
}
]
}
If the device were to see the level sensor go below 10% then an event would be raised and the broker contacted. A message like that below might be sent giving the current values of the points on the device and the analogue event causes as the level went below 10%. As for the digital event message above, the reason field “r” in the message shows 3 for s state change and 1 for the current value.
{
"p":
[
{
"ai": 0,
"v": [8, 8],
"q": [0, 0],
"ts": [1728590531263, 1728590530263],
"r": [1, 3]
},
{
"bi": 0,
"v": [1],
"ts": [1728590531263],
"r": [1]
}
]
}
The device described above contacts the broker once a day for a scheduled call. During that call the current values for all points and any collected events or logged data will be transferred to the broker. The example message below, shows the transfer of current values and also of the logged 10 minute values for the analogue input (level sensor). The “t” JSON which includes the initial time “s” and interval “i” information is used to set up the transfer of all values within the “v” array.
{
"p":
[
{
"ai": 0,
"v": [8],
"q": [0],
"ts": [1728590631263],
"r": [1]
},
{
"bi": 0,
"v": [1],
"ts": [1728590631263],
"r": [1]
}
{
"ai": 0,
"t":
{
"s": 1729710600000,
"i": 600000
}
"v": [ 23.0, 23.1, 23.6, 24.1, ... 19.2, 18.1, 18.3, 15.1 ]
}
]
}
A partial configuration change could be requested by a Supervisory Application (SA). The SA has access to the current device configuration from the broker, it also knows the configuration version associated with that. The example message below shows a partial configuration change which would take the configuration version from 123 to 124 if successful. The configuration changes a preconfigured analogue limit from 10% to 15%, see the “value” field.
{
"cVer": 124,
"full": false,
"source": "3cad5905-ea52-4d22-b862-a32fefe4e01e",
"analogueLimit": [
{
"parent": 0,
"parentType": "ai",
"num": 0,
"name": "Low",
"action": 2,
"dirctn": 1,
"value": 15.0,
"hyst": 1.0,
"enter": 10000,
}
],
}
If the partial configuration request shown above is accepted and enacted by the device, then the device will publish a new status message to the broker showing the updated configuration version as 124.
{
"pRef": "ACME_Device1_1-00",
"cVer": 124,
"time": 1728590831263
}
As well as publishing the status message with the new configuration version to the broker, the Field Device also publishes an updated configuration message. In the configuration change shown above, the new configuration published to the broker would have the configuration version changed and also the analogue limit changed from 10.0 to 15.0. Note that the example below does not include the entire configuration message, just exceprts around those parts which have changed.
{
"cVer": 124,
"full": true,
"device": [
{
"nid": "RES01",
... data is the same
"state0Pers": 60000,
"state1Action": 2,
"state1Pers": 1000
}
],
"analogueLimit": [
{
"parent": 0,
"parentType": "ai",
"num": 0,
"name": "Low",
"action": 2,
"dirctn": 1,
"value": 15.0,
"hyst": 1.0,
"enter": 10000,
}
],
}
Once the new configuration is enacted by the device, the device recalculates the state of the analogue input. The example message below shows the data message that would be sent out if the analogue point value was 13 and therefore now put the point into alarm.
{
"p":
[
{
"ai": 0,
"v": [13],
"q": [0],
"ts": [1728590831263],
"r": [3]
},
]
}
Lucid is a free, open source protocol that bridges a gap between Operational Technology (OT) and IoT technology.