Data Processing
| Note: The Gear Studio platform natively supports a wide variety of devices from different technologies. These devices do not require the use of scripting. The information on this page is useful for configuring new device models that are not natively supported by the platform. |
|---|
Introduction
As part of a device model configuration, you can create a script for processing data received from the device via MQTT, HTTP, or LoRaWAN. This allows:
- Processing each received payload (uplink)
- Updating the information of endpoints associated with the device, applying conversion functions to the data when necessary.
- Updating information about the device itself, such as RSSI levels, battery, etc., applying conversion functions to the data when necessary.
- Creating specific payloads destined for the device (downlink)
- Processing standard or custom commands defined in the Gear platform, and generating a payload with the format expected by the device.
Processing Received Payloads (Uplink)
To process each payload received from the device (regardless of whether it is received via HTTP, MQTT, or LoRaWAN), you can create a parseUplink function, as shown in the example below. This example is written assuming a temperature and humidity sensor that reports the temperature in the first byte of the payload, the humidity in the second byte, and the battery percentage in the third byte.
function parseUplink(device, payload)
{
// Payload is binary, so it's easier to handle as an array of bytes
var bytes = payload.asBytes();
// Verify payload contains exactly 3 bytes
if (bytes.length != 3)
return;
// Parse and store temperature
var temperatureSensor = device.endpoints.byType(endpointType.temperatureSensor);
if (temperatureSensor != null)
{
var temperature = bytes[0] & 0x7f;
if (bytes[0] & 0x80) // Negative temperature?
temperature -= 128;
temperatureSensor.updateTemperatureSensorStatus(temperature);
}
// Parse and store humidity
var humiditySensor = device.endpoints.byType(endpointType.humiditySensor);
if (humiditySensor != null)
{
var humidity = bytes[1];
humiditySensor.updateHumiditySensorStatus(humidity);
}
// Parse and store battery percentage
var batteryPercentage = bytes[2];
device.updateDeviceBattery({ percentage: batteryPercentage });
}In the example above, you can see a parseUplink function that processes a 3-byte payload and then uses that information to update the status of the device's endpoints (temperature sensor and humidity sensor), as well as the device's battery level.
The parseUplink function is automatically executed by the platform each time a payload is received for the device. The function receives the following parameters:
- device: this parameter is of type device and contains all information about the device that sent the payload, including the list of associated endpoints. For more information, see the device object reference.
- payload: this parameter is of type data payload and contains the payload received from the device. The payload object provides a series of methods that allow easy access to the payload content, such as:
- asBytes() reads the payload content as a byte array and is useful when the payload is binary.
- asString() reads the payload content as text and is useful when the payload is ASCII.
- asJsonObject() reads the payload content as a JSON object and is useful when the payload is in JSON format.
- asParsedObject() accesses data pre-parsed by an external platform. This option is available for platforms like Actility and The Things Stack, which allow data parsing before sending to the Gear Studio platform.
The payload object also has a port property, available for data received from LoRaWAN networks, which reflects the LoRaWAN port number to which the data was sent. Similarly, for data received via MQTT, there is a topic property that reflects the topic to which the data was sent.
The parseUplink function executes atomically, meaning data is only updated if the script executes successfully. In case of script execution errors, all changes will be reverted as if the payload had not been received. For this reason, it is important that the script handles error conditions correctly.
If the script does not include the parseUplink function, the received packet will be ignored.
Responses for HTTP Uplink Submissions
When uplinks are sent via HTTP, the platform will normally return a 200 status code and an empty body. However, this behavior can be changed by returning an HttpResponse object, specifying the information to return, including:
- Status code
- Content type
- Content
Below is an example of this.
function parseUplink(device, payload)
{
[...]
[ More code ]
[...]
var httpResponse = new HttpReponse();
httpResponse.statusCode = 200;
httpResponse.contentType = "application/json";
httpResponse.content.setAsJson({ textField: "some text", aNumber: 25 });
return httpResponse;
}For more information, see the HttpResponse object reference.
Building Payloads for the Device (Downlink)
To send data to the device (typically commands), you can create a buildDownlink function, as shown in the example below. This example is written assuming a device that contains a single endpoint of type appliance that can be turned on, turned off, and toggled. It is assumed that a single byte must be sent in the payload indicating the operation type.
function buildDownlink(device, endpoint, command, payload)
{
payload.port = 25; // This device receives commands on LoRaWAN port 25
payload.buildResult = downlinkBuildResult.ok;
switch (command.type) {
case commandType.onOff:
switch (command.onOff.type) {
case onOffCommandType.turnOn:
payload.setAsBytes([30]); // Command ID 30 is "turn on"
break;
case onOffCommandType.turnOff:
payload.setAsBytes([31]); // Command ID 31 is "turn off"
break;
case onOffCommandType.toggle:
payload.setAsBytes([32]); // Command ID 32 is "toggle"
break;
default:
payload.buildResult = downlinkBuildResult.unsupported;
break;
}
break;
default:
payload.buildResult = downlinkBuildResult.unsupported;
break;
}
}In the example above, you can see a buildDownlink function that processes a platform command and creates a 1-byte payload from it. The script only supports commands for on/off type endpoints, and therefore shows an error if any other type of command is attempted.
The buildDownlink function is automatically executed by the platform each time any command is sent to the device, regardless of whether the command is sent from an app, a scheduled action, etc. The function receives the following parameters:
- device: this parameter is of type device and contains all information about the device to which the command will be sent, including the list of associated endpoints. For more information, see the device object reference.
- endpoint: this parameter is of type endpoint and contains the data of the endpoint to which the command will be sent. This field can be null if the command is being sent to the device rather than a specific endpoint. For example, when sending a "reboot" command, the command is sent to the device since restarting an individual endpoint does not make sense.
- command: this parameter is of type command and contains the command that the platform will send. The function code normally uses the information in this object to build the payload that must be sent to the device. For more information about the command content, see this section.
- payload: this parameter is of type data payload and is used to create the payload that will ultimately be sent to the device. The payload object provides a series of methods that allow modifying its content, such as:
- setAsBytes() writes the payload content using a byte array.
- setAsString() writes the payload content as text and is useful when the payload is ASCII.
- setAsJsonObject() writes the payload content as a JSON object and is useful when the payload is in JSON format.
The payload object also has a port property, available for devices with LoRaWAN connectivity, which reflects the LoRaWAN port number to which the data will be sent. Similarly, for devices with MQTT communication, there is a topic property that allows specifying the topic to which the data will be sent.
If the script does not include the buildDownlink function, the command will be rejected indicating that it is not supported.