A message handler custom function can be used to enrich the data sent by the connected device. The custom function is written using the deluge scripting language. In this document, we provide a sample code to demonstrate how a message handler operates, along with a detailed breakdown of the code's functionality.
- headerMap = header.toMap();
- deviceid = headerMap.get("deviceid");
- receivedtime = headerMap.get("occurred_timestamp");
- topic = headerMap.get("topic");
- communication_status_flag = headerMap.get("data_internal");
- state_memory = headerMap.get("state_memory");
- if(state_memory == null)
{
state_memoryMap = Map();
}
- else
{
state_memoryMap = state_memory.toMap();
}
- if(communication_status_flag == false && topic == "telemetry")
{
payload = message.toMap();
if(payload.containKey("data"))
{
deviceMessage = payload.get("data");
}
else
{
deviceMessage = payload;
}
} - else if(communication_status_flag == true)
{
deviceMessage = Map();
deviceMessage.put("header", headerMap);
} - output = Map();
- output.put("device_message",deviceMessage);
- return output;
This code is provided by default when you create a message handler custom function. Refer to this document to learn how to execute and test the code.
Code Breakdown
The messages sent by connected devices are stored and accessible via the header and message arguments. To process these messages, necessary data must be extracted from these arguments. The header argument contains metadata such as Device ID, communication status flag, Status Type, Message Type, timestamp, and State Memory (if enabled when creating the message handler custom function).
In the Deluge script, data is handled using Map objects. In the code snippet below, data from the header argument is assigned to a variable named headerMap, which is initialized as a Map object. Key data elements such as device id, received time, topic, and communication_status_flag are then extracted and stored in corresponding variables.
- headerMap = header.toMap();
- deviceid = headerMap.get("deviceid");
- receivedtime = headerMap.get("occurred_timestamp");
- topic = headerMap.get("topic");
- communication_status_flag = headerMap.get("data_internal");
Next, if state memory is enabled for the message handler, the state_memory variable must be initialized and stored as a map object. The following block of code accomplishes this. In the code block below, the state memory is saved to a variable named state_memoryMap.
- state_memory = headerMap.get("state_memory");
- if(state_memory == null) { state_memoryMap = Map(); }
- else
{ state_memoryMap = state_memory.toMap(); }
Once the basic values are extracted and the state memory is initialized, the next step involves determining the message type of the received message. This is done by checking the value of the communication_status_flag variable. If the value is true, the message pertains to the device's connection status, indicating whether the device is connected or disconnected. If the value is false, the message is a Device Message, which means it contains the payload sent by the device. The following block of code identifies this distinction.
First, the message type is confirmed. If it is a payload message, the data from the message argument is extracted and stored as a map object in a variable called payload. From this payload, the actual data is then extracted and stored in a variable called deviceMessage.
Conversely, if it is a connection status message, the deviceMessage
variable is assigned as an empty Map object. This step is necessary because the code must return a Map object, regardless of the message type being processed.
- if(communication_status_flag == false && topic == "telemetry")
{
payload = message.toMap();
if(payload.containKey("data"))
{
deviceMessage = payload.get("data");
}
else
{
deviceMessage = payload;
}
}
- else if(communication_status_flag == true)
{
deviceMessage = Map();
}
With the deviceMessage values handled, the final message to be returned is assigned to a variable called output. It's important to note that the returned output
must be a Map object to conform to the custom function's requirement.
- output = Map();
- output.put("device_message",deviceMessage);
- return output;
While executing the code described above, it will either output the message value as received by the application or return a null value if the message is related to connection status. Here’s a block of code that takes the received message, adds 5 to it, and outputs the value.
Add the below line of code before the code line output = Map().
- deviceMessage = deviceMessage.get('value')+5;
To test this operation, provide the input {'value': 6} in the Messages field when executing the custom function. This will adjust the value in deviceMessage to 11, and will be sent as the output of the message handler function.