Skip to content

Data Transformations

Functional translations in Device Services allow the automatic transformation of data as it is collected. These transformations are controlled by Lua scripts that can be injected into a device service at run-time. The Lua scripts can intercept data, apply transformations, and deliver the transformed data northbound to the Edge Xpert message bus as standard.

All device services are supported.

Enable the Lua Transform Component

The Lua Transform Component inside a device service is disabled by default.

To enable it, use Docker Compose Override to set the environment variable USETRANSFORMSCRIPT to true for the device service.

In the example below, we enable the Lua Transform Component in the BACnet/IP Device Service:

services:
  device-bacnet-ip:
    environment:  
      USETRANSFORMSCRIPT: "true"

Lua Script Example

In order to transform data, you need to create a Lua script. This can be created in a regular text file.

The following example converts the received readings from Celsius to Fahrenheit:

for k,v in pairs(data.readings) do
  -- Convert Celsius to Fahrenheit
  if v.units == 'C' then
    data.readings[k].units = 'F'
    data.readings[k].value = data.readings[k].value * 9 / 5 + 32
  end
end

Once created, save as a .lua file. We saved this example as celsius-to-fahrenheit.lua.

The predefined variable data is a Lua table representing an Edge Xpert Event. This contains the following information:

  • deviceName
  • profileName
  • sourceName
  • readings
    • origin
    • deviceName
    • profileName
    • resourceName
    • valueType
    • units
    • value

Without Lua translations, value is converted to a string. However, with a Lua script enabled, value keeps its original data type. This allows you to directly perform calculations or transformations on the value.

In this Lua script example, Celsius readings are detected by checking the units property of the device resource, which is defined in the device profile. For example:

name: bacnet-sim-profile
deviceResources:
    - name: analog_input_0-present-value
      isHidden: false
      properties:
        valueType: Float32
        readWrite: RW
        units: C
      attributes:
        instance: 0
        property: 85
        type: 0
deviceCommands: []

Upload Lua Script for Device Service via Edge Xpert Manager

  1. Start Edge Xpert Manager, along with the BACnet Device Service and simulator:

    edgexpert up device-bacnet-ip bacnet-sim xpert-manager
    
  2. Open a browser and go to http://localhost:9090. The default username/password is admin/admin.

  3. Select Devices from the main menu:

    Devices Page

  4. Select the Device Services tab:

    Device Services Page

  5. Click the horizontal three-dot menu on the service where you want to upload the Lua script. Select Edit:

    Edit Device Service

  6. Choose the Lua script file you wish to apply and click Save:

    Apply Lua Script

You can now proceed as standard to add the device and device profile.

All data gathered from the device service will now be transformed as defined in the Lua script and will be available in Edge Xpert for processing, analysis, and delivery as normal.

Upload Lua Script for Device Service via REST APIs

The Device Service REST APIs have been instrumented with an additional parameter that allows for the transform script to be injected into the running service.

See the Swagger definition for further information

Swagger definition

As above, this example uses the BACnet Device Service and simulator. To upload a Lua script over REST API, follow the steps below:

  1. Start the BACnet Device Service and simulator:

    edgexpert up device-bacnet-ip bacnet-sim
    
  2. Send a PATCH request with the following body:

    curl -X 'PATCH' \
      'http://<core-metadata-address>/api/v2/deviceservice' \
      -H 'accept: application/json' \
      -H 'Content-Type: application/json' \
      -d '[
      {
        "apiVersion": "v2",
        "service": {
          "name": "device-bacnet-ip",
          "transformScript": "<path/<to>/<file>/celsius-to-fahrenheit.lua"
        }
      }
    ]'
    

    Note

    Ensure you replace the placeholders with the appropriate Lua file path and core-metadata adress. You can find the address for core-metadata with the following command:

    edgexpert ip | grep core-metadata
    

    If successful, this should return: [{"apiVersion":"v2","statusCode":200}]

    When following this example, you can also confirm the Lua script has taken effect by checking the Docker logs for the simulator:

    $ docker logs -f bacnet-sim
    Running in IP mode
    IOTech BACnet Simulator
    BACnet Stack Version 1.0.5
    BACnet Device ID: 123
    Max APDU: 1476
    Loading lua script...
    Create 2 AnalogValue instances
    Create 2 AnalogOutput instances
    Create 2 AnalogInput instances
    Loaded lua script sucessfully.