akenza.io
WebsiteAPI DocumentationWhat's newLogin
  • Overview
  • Getting Started
    • Connect a Device
  • Changelog
  • General
    • Applications
    • Organization context
    • Workspace Context
    • Users
      • User Roles
  • Device Management
    • Managing an organization
      • API keys
      • Users (Organization)
        • Add & removing users from your organization
    • Managing a workspace
      • General Settings
        • Device Lifecycle Reports
        • Workspace properties
        • Occupancy settings
        • Device Setup Assistant
      • Custom fields
      • Tags
      • Users (Workspace)
    • Devices
      • Device
      • Device Simulator
      • Bulk actions
      • Bulk import CSV templates
    • Rules
      • Input
      • Logic blocks
        • Comparison
        • Custom Logic
          • Logic Block Scripting
      • Timed Rules
      • Rule Actions
        • Downlink
    • Data Flows
      • Device Connectors
        • Device Security
          • Using Device Credentials
            • Creating Public/Private Key Pairs
            • Using JSON Web Tokens (JWTs)
              • Python
              • Java
        • HTTP
        • MQTT
        • CoAP
        • LoRaWAN
          • Connectivity Management
          • Swisscom LoRaWAN
          • The Things Network
          • Loriot
          • Actility’s ThingPark Wireless
          • EWZ
          • Cibicom
          • Helium
          • ChirpStack
        • NB-IoT
        • mioty
        • Disruptive Technologies
        • VergeSense
        • Spaceti
        • Haltian
      • Device Types
        • Custom Device Types
          • Uplink
          • Downlink
          • Scripting
        • Library
      • Output Connectors
        • Databases
          • akenza DB
          • InfluxDB
          • SQL Databases
        • Streaming
          • Webhook
          • Azure IoT Hub
          • AWS Kinesis
          • Google Cloud Pub/Sub
          • Apache Kafka
        • Notifications
          • E-Mail
          • SMS
          • Microsoft Teams
          • Slack
    • Custom Components
    • Integrations
    • Reference
      • REST API
        • Filtering
        • Querying Device Data
      • WebSocket API
      • Scripting
        • Stateful Operations
        • Utility Functions
      • Payload Templating
  • Reference
  • Dashboard Builder
    • Managing Dashboards
      • Embedding dashboards
    • Components
      • Map
      • Floorplan
  • Device Setup Assistant
    • Device Setup Assistant - Overview
  • Tutorials
    • BI Tools
      • Grafana Data Source Plugin
      • How to build a dashboard with Retool
      • How to analyze data with AWS QuickSight
    • Devices
      • How to integrate the XDK device from Legic via MQTT on akenza
      • How to connect the Disruptive Technologies-cloud on akenza
      • How to send Downlinks to the Kuando Busylight device
      • How to integrate an Arduino device via MQTT on akenza
      • Integrate a MClimate Vicki LoRaWAN Radiator Thermostat on akenza
      • How to integrate an ERS Elsys device with Loriot on akenza
      • How to integrate the IAM Decentlab device with TTN on akenza
      • How to integrate the Seeed SenseCAP T1000 tracker on akenza
      • How to integrate a Swisscom Multisense device on akenza
    • Notifications
      • How to send SMS notifications
      • How to send notifications to Slack
      • How to send notifications to Microsoft Teams
    • Enterprise solutions
      • How to send data to Azure IoT Hub
      • How to send data to the Google Cloud Pub/Sub
      • How to send data to InfluxDB
      • How to send data to AWS Kinesis
      • How to send data to Azure Event Hubs with Apache Kafka
    • IoT Starter Kits
      • How to integrate the IAQ Kit with Actility on akenza
      • How to integrate the CoWork Kit with Actility on akenza
      • How to integrate the Smart Building Kit with Actility on akenza
      • How to integrate the Pepperl+Fuchs Kit with Actility on akenza
  • Support Center
    • FAQ
    • Status Page
    • Service Desk
    • Request a feature
  • Deprecated
    • SIM-Cards
    • Everynet
    • Sigfox
    • How to connect the Yanzi Lifecycle cloud on akenza
Powered by GitBook
On this page
  • Rule logic script
  • Event Object
  • Emitting actions
  • Re-invoking the rule engine
  • Rule Action - Custom Payload
  • Emitting a timer
  • Event examples
  • Logic Block uplink event
  • Logic Block timer event
  • Logic Block last sample timer event

Was this helpful?

  1. Device Management
  2. Rules
  3. Logic blocks
  4. Custom Logic

Logic Block Scripting

Documentation of logic block scripting concepts

For general scripting concepts refer to this page: Scripting

Rule logic script

The Rule logic script defines the custom logic that is evaluated during rule runs.

function consume(event) {
  var temperature = event.inputs.temperature;
  var threshold = event.properties.tempThreshold;

  if (temperature < threshold) {
    emit("action", {
      message: `it is too cold: the temperature is ${temperature}°C`,
    });
  }
}

Once a Custom Logic Block is saved, it can be selected as a logic block when creating a rule. Inputs need to be linked to an input device or tag and parameters need to be set.

Further, one or more actions need to be defined. The templating syntax can be used to access the results of a Custom Logic Block {{result.*}}. For example, {{result.message}} for the script shown above.

Custom logic timer

There is also the possibility to emit a timer inside the custom logic block.

When emitting the timer event, two params can be specified

  • runAt required, a date which needs to be at least 15 seconds in the future

  • meta optional, object which can contain any values

The meta object will be available when the rule is triggered by that timer and can be accessed at timer.meta during script run. This can provide useful information for the next timed run or help uniquely identify timers when running them.

function consume(event) { 
  let time = new Date();
  time = new Date(time.setDate(time.getDate() + 1));
  time = time.setHours(0,0,0,0);
  emit("timer", {runAt: new Date(time), meta: {"foo": "bar"}});
}

Refer to Stateful Operations for more information on how to share data between runs of a rule.

Event Object

The Custom Logic Block script is invoked with the event object as param. It contains the following properties & strucutre:

  • inputs object, contains the values of the specified variables

  • state object, contains the user defined rule state

  • type string, indicates how the rule was invoked (either timer or uplink)

  • dataSources object, see data source properties

  • device object, see device properties

  • properties object, contains the user defined properties of the custom logic block

Note: if type has the value of timer certain properties will behave differently:

  • the variable values of the inputs object will be null

  • dataSources will be an empty object

  • device will be undefined

Device Properties

The following properties of a device can be accessed when using template syntax.

Note: The prefix device. is always required in order to access sub properties.

  • name the device name

  • description the device description

  • integrationId the integrationId of the device (only for LoRaWAN devices)

  • workspaceId the workspaceId of the device

  • dataFlowId the data flow id of the device

  • connectivity the connectivity of the device

  • id the akenza device id

  • deviceId the unique device id

Data Source Properties

The following properties of a data source can be accessed when using template syntax.

To access a specific data source, use dataSources.X where X is the number of the data source as specified in the rule (starting at 1).

Some properties can be null in certain circumstances (e.g. the correlationId or the device) if e.g. the rule was triggered by a timer event or the data source is set to access the last sample.

Note: The prefix dataSources.X. is always required in order to access sub properties.

  • correlationId the correlation id of the data source (only available if the data source was triggering the flow)

  • device the complete device object. See Device Properties for sub properties

  • deviceId the unique device id

  • akenzaDeviceId the akenza device id

  • topic the topic of the sample

  • timestamp the timestamp of the sample

  • data.* access any values of the sample.

  • meta.* access any values of the meta object

  • uplinkMeta the complete uplink meta object

  • trigger boolean, indicates whether the data source has triggered the uplink

  • deviceInput boolean, indicates if the data source is a device

  • tagInput boolean, indicates if the data source is a tag

The values related to the sample (namely correlationId, topic, timestamp, data, meta and uplinkMeta) are resolved based on which data source triggered the rule evalution. If the data source is triggering (trigger = true) the rule, the values will be the one from the triggering uplink. Otherwise the values will correlate the most recent stored sample.

Uplink Meta Properties

The following properties of uplink meta data can be accessed when using template syntax

Note: The prefix uplinkMeta. is always required in order to access sub properties.

  • dataReceived the ISO-8601 timestamp when the data was recieved

  • bytesReceived the number of bytes received in the uplink request

  • processingStart the ISO-8601 timestamp when the processing was started

  • scriptRunUplinkStart the ISO-8601 timestamp when script run was started

  • scriptRunUplinkEnd the ISO-8601 timestamp when script run ended

  • processingEnd the ISO-8601 timestamp when the processing ended

  • outputProduced the ISO-8601 timestamp when all output were produced

  • uplinkDuration the ISO-8601 duration of the whole uplink flow

  • processingDuration the IOS-8601 duration of the processing

  • scriptRunningDuration the ISO-8601 duration of the script run

Emitting actions

If a condition is met, an action has to be emitted that will invoke the consecutive rule actions.

if (currentTemperature > threshold) {
  emit("action", {
    message: `temperature (${currentTemperature} °C) is above threshold (${threshold} °C)`,
  });
}

Re-invoking the rule engine

It is possible to re-invoke the rule engine by enabling the setting in the rule action. This is useful, to apply another rule to the output of a custom logic block.

if (currentTemperature > threshold) {
  emit("action", {
    data: { temperature, threshold, message: `temperature (${currentTemperature} °C) is above threshold (${threshold} °C)` },
    topic: "alert"
  });
}java

If the topic is specified in the emit action, it will override the one specified in the custom akenza db rule action.

Rule Action - Custom Payload

Emitting a timer

By emitting a timer, you can schedule a rule to run be invoked again in the future.

emit("timer", {
    runAt: new Date(Date.now() + 60 * 60 * 1000), //the timestamp of when the rule should be invoked
    meta: {} //metadata that will be available during the invocation of the time
  });

meta can then be accessed using event.timer.meta.

Event examples

Logic Block uplink event

A decoded uplink that triggers a custom logic block, looks as follows. Note that the state is controlled by the script author (see Stateful Operations):

{
  "inputs": {
    "occupied": false
  },
  "state": {
    "devices": {
      "00000000000000ff": {
        "lastOccupiedTimestamp": 1716553293784,
        "currentlyOccupied": false,
        "lastMessageTimestamp": 1716553385376,
        "sent": true
      }
    }
  },
  "type": "uplink",
  "dataSources": {
    "1": {
      "correlationId": "77777777-7777-7777-7777-77777777",
      "device": {
        "connectivity": "LORA",
        "customFields": {
          "FloorNumber": 1,
          "SiteId": "ZURICH",
          "IsWarmDeskEnabled": "true",
          "SpaceId": "1OGR35"
        },
        "name": "Meeting Room R35",
        "description": "",
        "id": "00000000000000ff",
        "deviceId": "1234567891012131",
        "workspaceId": "2900000000000000",
        "tags": [
          "occupancy",
          "climate"
        ]
      },
      "deviceId": "1234567891012131",
      "akenzaDeviceId": "00000000000000ff",
      "topic": "occupancy",
      "timestamp": "2024-05-24T12:38:06.122Z",
      "data": {
        "occupied": false,
        "motionCount": 0
      },
      "trigger": true,
      "deviceInput": false,
      "tagInput": true,
      "tagCombinationInput": false,
      "triggerOnUplink": true,
      "lastSample": false
    }
  },
  "device": {
    "connectivity": "LORA",
    "customFields": {
      "FloorNumber": 1,
      "SiteId": "ZURICH",
      "SpaceId": "1OGR35"
    },
    "name": "Meeting Room R35",
    "description": "",
    "id": "00000000000000ff",
    "deviceId": "1234567891012131",
    "workspaceId": "2900000000000000",
    "tags": [
      "occupancy",
      "climate"
    ]
  },
  "numberOfInvocations": 0,
  "properties": {}
}

Logic Block timer event

A time-based event that triggers a custom logic block, looks as follows. Note that the state is controlled by the script author (see Stateful Operations):

{
  "inputs": {
    "occupied": null
  },
  "state": {
    "devices": {
      "00000000000fffff": {
        "lastOccupiedTimestamp": 1716553293784,
        "currentlyOccupied": false,
        "lastMessageTimestamp": 1716560583110,
        "sent": false
      }
    }
  },
  "type": "timer",
  "dataSources": {},
  "numberOfInvocations": 0,
  "properties": {}
}

Logic Block last sample timer event

A time-based event that triggers a custom logic block, looks as follows.

Note that the state is controlled by the script author (see Stateful Operations):

{
  "inputs": {
    "temperature": 23.84
  },
  "state": {},
  "type": "timer",
  "dataSources": {
    "1": {
      "correlationId": "77777777-7777-7777-7777-777777777777",
      "device": {
        "connectivity": "LORA",
        "customFields": {},
        "name": "Watteco Senso",
        "description": null,
        "id": "1998877667788991",
        "deviceId": "000000000000ffff",
        "workspaceId": "2929292929292929",
        "tags": []
      },
      "deviceId": "000000000000ffff",
      "akenzaDeviceId": "1998877667788991",
      "topic": "default",
      "timestamp": "2024-05-24T13:20:14.869Z",
      "data": {
        "temperature": 23.84,
        "humidity": 51.3,
        "voc": 553,
        "co2": 518
      },
      "meta": null,
      "uplinkMeta": {
        "dataReceived": "2024-05-24T13:20:14.150224453Z",
        "bytesReceived": 952,
        "processingStart": "2024-05-24T13:20:14.220414139Z",
        "scriptRunUplinkStart": null,
        "scriptRunUplinkEnd": null,
        "processingEnd": "2024-05-24T13:20:14.259641209Z",
        "outputProduced": null,
        "ruleResolutionStart": "2024-05-24T13:20:14.805071863Z",
        "ruleResolutionEnd": null,
        "ruleExecutionStart": null,
        "ruleExecutionEnd": null,
        "uplinkDuration": "PT0S",
        "processingDuration": "PT0.03922707S",
        "ruleResolutionDuration": "PT0S",
        "ruleExecutionDuration": "PT0S",
        "scriptRunningDuration": "PT0S"
      },
      "trigger": false,
      "deviceInput": true,
      "tagInput": false,
      "tagCombinationInput": false,
      "triggerOnUplink": false,
      "lastSample": true
    }
  },
  "numberOfInvocations": 0,
  "properties": {}
}
PreviousCustom LogicNextTimed Rules

Last updated 5 months ago

Was this helpful?

Note that the emit action is expected to have a specific format (same structure as the sample output in device type scripts), see for details. This means that properties like topic, timestamp (optional) and data should be provided and will be processed in subsequent rules.

When using a in the rule action, make sure to use {{result.*}} to access data that has been emitted as part of the rule action. For example, to store the result of a rule action that has been used to re-invoke the rule engine, use {{result.data}}. Otherwise the whole result object will be stored as a sample meaning topic, timestamp, data and meta (if specified) will be contained in the data object.

custom payload template
Emit Function