计算字段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
布尔参数。
方法 | 默认行为 ( | 替代方案( |
| 忽略 | 若存在任何 |
| 忽略 | 若存在任何 |
| 忽略 | 若存在任何 |
| 忽略 | 若存在任何 |
| 忽略 | 若存在任何 |
| 忽略 | 计数所有值,包括 |
| 忽略 | 即使该值为 |
| 忽略 | 即使该值为 |
| 忽略 | 若存在任何 |
使用示例:
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),
};
}
合并时间序列参数
时间序列滚动参数可以合并,以对齐多个数据集的时间戳。
方法 | 功能描述 | 返回 | 示例 |
| 与单个滚动参数合并,对齐timestamp并用前一个有效值填充缺失值 | 合并后的对象,包含 | |
| 与多个滚动参数(数组)合并,对齐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" }
}
}