脚本计算_物联网平台_边缘计算网关

计算字段TBEL脚本函数

calculate() 函数是一个用户自定义脚本,支持通过TBEL对遥测数据和属性数据进行自定义计算。该函数接收计算字段设置中配置的参数,以及一个额外的ctx上下文对象——该对象存储latestTs(最新时间戳)并可调用所有参数。

函数签名

function calculate(ctx, arg1, arg2, ...): object | object[]

支持的参数类型

计算字段配置中支持一下三类参数:

属性与最新遥测(物模型)参数

此类参数为单值类型,支持以下数据类型:

  • 布尔值(boolean
  • 64位整数(int64 / long
  • 双精度浮点数(double
  • 字符串(string
  • JSON 对象

示例: 将温度值从华氏度换算为摄氏度

var temperatureC = (temperatureF - 32) / 1.8;
return {
  temperatureC: toFixed(temperatureC, 2),
};

或者,使用ctx将参数作为对象访问:

{
  "temperatureF": {
    "ts": 1740644636669,
    "value": 36.6
  }
}

你可能会注意到,该对象同时包含参数的 value 和其时间戳 ts。让我们修改华氏温度转换为摄氏温度的函数,使其也返回时间戳信息:

var temperatureC = (temperatureF - 32) / 1.8;
return {
  ts: ctx.args.temperatureF.ts,
  values: { temperatureC: toFixed(temperatureC, 2) },
};

时间序列滚动参数

这些参数包含‌定义时间窗口‌内的时间序列数据。示例格式如下:

{
  "temperature": {
    "timeWindow": {
      "startTs": 1740643762896,
      "endTs": 1740644662896
    },
    "values": [
      { "ts": 1740644350000, "value": 72.32 },
      { "ts": 1740644360000, "value": 72.86 },
      { "ts": 1740644370000, "value": 73.58 },
      { "ts": 1740644380000, "value": "NaN" }
    ]
  }
}

值始终会被转换为 double 类型;若转换失败,则使用 NaN 表示。可通过 isNaN(double): boolean 函数检查值是否为‌有效数字‌。

示例: 访问时间序列滚动参数数据

var startOfInterval = temperature.timeWindow.startTs;
var endOfInterval = temperature.timeWindow.endTs;
var firstItem = temperature.values[0];
var firstItemTs = firstItem.ts;
var firstItemValue = firstItem.value;
var sum = 0.0;
// 遍历所有值并计算总和(使用 foreach 循环)
foreach(t: temperature) {
  if(!isNaN(t.value)) { // 检查值是否为有效数字
    sum += t.value;
  }
}
// 遍历所有值并计算总和(使用 for 循环)
sum = 0.0;
for (var i = 0; i < temperature.values.size; i++) {
  sum += temperature.values[i].value;
}
// 使用内置函数计算总和
sum = temperature.sum();
滚动参数的内置方法

时间序列滚动参数支持用于计算的内置函数。这些函数可接受一个可选的 ignoreNaN 布尔参数。

方法

默认行为 (ignoreNaN = true)

替代方案(ignoreNaN = false)

max()

忽略 NaN 值,返回最高值

若存在任何 NaN 值,则返回 NaN

min()

忽略 NaN 值,返回最低值。

若存在任何 NaN 值,则返回 NaN

mean(), avg()

忽略 NaN 值,计算平均值。

若存在任何 NaN 值,则返回 NaN

std()

忽略 NaN 值,计算标准差。

若存在任何 NaN 值,则返回 NaN

median()

忽略 NaN 值,返回中位数。

若存在任何 NaN 值,则返回 NaN

count()

忽略 NaN 值,计数。

计数所有值,包括 NaN

last()

忽略 NaN 值,返回最新值。

即使该值为 NaN,也返回最后一个值。

first()

忽略 NaN 值,返回最旧值。

即使该值为 NaN,也返回第一个值。

sum()

忽略 NaN 值,计算总和。

若存在任何 NaN 值,则返回 NaN

使用示例:

var avgTemp = temperature.mean(); // 返回 72.92
var tempMax = temperature.max(); // 返回 73.58
var valueCount = temperature.count(); // 返回 3

var avgTempNaN = temperature.mean(false); // 返回 NaN
var tempMaxNaN = temperature.max(false); // 返回 NaN
var valueCountNaN = temperature.count(false); // 返回 4

该函数使用**海拔(单个值)温度(时间序列滚动参数)**来计算空气密度。

function calculate(ctx, altitude, temperature) {
  var avgTemperature = temperature.mean(); // 获取平均温度
  var temperatureK = (avgTemperature - 32) * (5 / 9) + 273.15; // 将华氏度转换为开尔文

  // 基于海拔估算气压
  var pressure = 101325 * Math.pow(1 - 2.25577e-5 * altitude, 5.25588);

  // 空气密度公式
  var airDensity = pressure / (287.05 * temperatureK);

  return {
    airDensity: toFixed(airDensity, 2),
  };
}
合并时间序列参数

时间序列滚动参数可以合并,以对齐多个数据集的时间戳。

方法

功能描述

返回

示例

merge(other, settings)

与‌单个‌滚动参数合并,对齐timestamp并用‌前一个有效值‌填充缺失值

合并后的对象,包含timewindow和对齐后的值



mergeAll(others, settings)

与‌多个‌滚动参数(数组)合并,对齐timestamp并用‌前一个有效值‌填充缺失值

合并后的对象,包含timewindow和对齐后的值



参数详解

参数

描述

otherothers

要合并的‌单个‌滚动参数(other)或‌多个‌滚动参数数组(others

settings(可选)

配置对象,包含以下关键选项:
ignoreNaN:布尔值,控制是否忽略NaN值(默认通常为false,即保留NaN
timewindow:自定义时间窗口(比如'1m'表示1分钟窗口),用于对齐timestamp

示例: 冷冻室温湿度分析

该函数合并 ‌温度‌ 数据与冰箱的 ‌除霜‌ 状态数据。随后分析合并后的数据,识别出“冰箱未处于除霜模式,但内部空气温度过高(> -5°C)”的场景。

function calculate(ctx, temperature, defrost) {
  var merged = temperature.merge(defrost);
  var result = [];

  foreach(item: merged) {
    if (item.v1 > -5.0 && item.v2 == 0) {
      result.add({
        ts: item.ts,
        values: {
          issue: {
            temperature: item.v1,
            defrostState: false
          }
        }
      });
    }
  }

  return result;
}

结果是一个可用于配置报警规则的问题列表:

[
  {
    "ts": 1741613833843,
    "values": {
      "issue": {
        "temperature": -3.12,
        "defrostState": false
      }
    }
  },
  {
    "ts": 1741613923848,
    "values": {
      "issue": {
        "temperature": -4.16,
        "defrostState": false
      }
    }
  }
]

函数返回格式

函数的返回格式取决于计算字段设置中配置的输出类型(默认为‌时间序列‌)。

消息时间戳

ctx 对象还包含 latestTs 属性,该属性代表输入参数中遥测数据的‌最新时间戳‌(单位为毫秒)。当函数返回‌时间序列对象‌时,可使用 ctx.latestTs 显式设置结果输出的时间戳。

var temperatureC = (temperatureF - 32) / 1.8;
return {
  ts: ctx.latestTs,
  values: {
    temperatureC: toFixed(temperatureC, 2),
  },
};

这确保了计算得到的数据点与触发遥测的时间戳保持一致。

时间序列输出

函数必须返回一个(带有或不带时间戳的)JSON 对象或数组。下方示例将返回 5 个数据点:‌空气密度‌(浮点型)、‌湿度‌(整型)、‌HVAC 开启状态‌(布尔型)、‌HVAC 状态‌(字符串型)和‌配置‌(JSON 对象):

无时间戳:

{
  "airDensity": 1.06,
  "humidity": 70,
  "hvacEnabled": true,
  "hvacState": "IDLE",
  "configuration": {
    "someNumber": 42,
    "someArray": [1, 2, 3],
    "someNestedObject": { "key": "value" }
  }
}

带时间戳:

{
  "ts": 1740644636669,
  "values": {
    "airDensity": 1.06,
    "humidity": 70,
    "hvacEnabled": true,
    "hvacState": "IDLE",
    "configuration": {
      "someNumber": 42,
      "someArray": [1, 2, 3],
      "someNestedObject": { "key": "value" }
    }
  }
}

包含多个时间戳和不同 ‌airDensity‌ 值的数组:

[
  {
    "ts": 1740644636669,
    "values": {
      "airDensity": 1.06
    }
  },
  {
    "ts": 1740644636670,
    "values": {
      "airDensity": 1.07
    }
  }
]

属性输出

该函数必须返回‌不包含时间戳信息‌的 JSON 对象。下方示例返回 5 个数据点:空气密度(双精度浮点型)、湿度(整型)、HVAC 启用状态(布尔型)、HVAC 状态(字符串型)和配置(JSON 对象):

{
  "airDensity": 1.06,
  "humidity": 70,
  "hvacEnabled": true,
  "hvacState": "IDLE",
  "configuration": {
    "someNumber": 42,
    "someArray": [1, 2, 3],
    "someNestedObject": { "key": "value" }
  }
}
本文通过 YUQUE WORDPRESS 同步自语雀
云腾五洲-AI助理