属性下发预处理规则
属性下发预处理规则
属性下发预处理规则 的触发时间,是在云平台向设备端实际下发属性之前。适合用于对设备下发属性做必要的内容增减、格式转换、二次计算等。
目前支持的操作如下:
- 预处理函数
预处理函数
提供了可编程的云函数,支持 Javascript
编程语言,如下:
module.exports = function (push_attributes) {
/**
* push_attributes: 下发的属性对象,同时作为函数返回值。函数中可更新属性对象。
*/
return push_attributes;
}
提示
当您在消息规则中编辑云函数时,可以多多使用在线调试功能,帮助您验证代码的准确性,并提升开发速度。详细介绍请浏览:每日调用上亿次的消息规则云函数,如何在线测试?。
示例:自动实现多个继电器互斥
这是一个最简单的例子,帮助您快速了解属性下发预处理的工作机制。
某设备端有两个继电器,属性分别是 relay1
和 relay2
,我们希望两个继电器总是互斥。
编写属性下发预处理函数如下:
module.exports = function (push_attributes) {
if (push_attributes.relay1 !== undefined) {
push_attributes.relay2 = !push_attributes.relay1;
}
if (push_attributes.relay2 !== undefined) {
push_attributes.relay1 = !push_attributes.relay2;
}
return push_attributes;
}
有了这个属性下发预处理规则后,当我们在平台操作 relay1
闭合,平台原本要下发消息:
{
"relay1": true
}
但由于存在属性下发预处理函数,平台实际会下发的消息是:
{
"relay1": true,
"relay2": false
}
于此同时,在平台的设备属性状态中,也可以看到 relay2
属性值同步更新为 false
。
提示
在平台操作 relay1
闭合,具体的方法非常多,例如:
- 在控制台的设备详情页中,点击相应的属性开关。
- 在控制台的可视化看板中,点击相应的属性开关。
- 在控制台的设备调试中,输入下发属性的 JSON。
- 在用户应用 ThingsX App(包括iOS/Android/微信小程序)中,点击相应的属性开关。
- 在用户应用 ThingsXS 的设备详情页中,点击相应的属性开关。
- 编写程序,调用项目 HTTP API,下发响应的属性。
示例:在互斥控制模式下,实现多个继电器互斥
在上边的示例基础上,我们增加一个逻辑,当设备的控制模式属性 control_mode
设置为互斥模式时,两个继电器 relay1
和 relay2
总是互斥。
修改预处理函数如下:
module.exports = function (push_attributes) {
// 读取设备当前所有属性
var attrs = Cloud.getCurrentAttributes();
// 判断控制模式是否为互斥模式
if (attrs.control_mode == 'mutual') {
if (push_attributes.relay1 !== undefined) {
push_attributes.relay2 = !push_attributes.relay1;
}
if (push_attributes.relay2 !== undefined) {
push_attributes.relay1 = !push_attributes.relay2;
}
}
return push_attributes;
}
示例:记录继电器操作次数
假设我们要记录用户对继电器属性 relay1
操作的次数,可以写一个这样的预处理函数,生成 relay1_count
这个属性,统计继电器开关的总下发次数。
module.exports = function (push_attributes) {
if (push_attributes.relay1 !== undefined) {
// 读取设备当前的属性
var curr_attrs = Cloud.getCurrentAttributes();
if (curr_attrs.relay1_count === undefined) {
// 上次计数count不存在,说明是首次下发
push_attributes.relay1_count = 1;
} else {
// 上次计数存在,本次计数+1
push_attributes.relay1_count = curr_attrs.relay1_count + 1;
}
}
return push_attributes;
}
以上函数通过使用 JavaScript 的 ||
运算符,还可以进一步简化为:
module.exports = function (push_attributes) {
if (push_attributes.relay1 !== undefined) {
// 读取设备当前的属性
var curr_attrs = Cloud.getCurrentAttributes();
// 本次计数+1,上次计数如果不存在则默认为0
push_attributes.relay1_count = (curr_attrs.relay1_count || 0) + 1;
}
return push_attributes;
}
在此基础上,还可以改为只统计当日的下发次数,思考一下如何实现呢?
示例:记录属性今日下发次数
这个例子中,通过属性下发预处理规则,生成 relay1_count
这个属性,统计继电器属性 relay1
在当日的下发次数。
module.exports = function (push_attributes) {
if (push_attributes.relay1 !== undefined) {
// 读取设备当前的属性
var curr_attrs = Cloud.getCurrentAttributes();
// 读取上次的计数,如果不存在则默认为0
var relay1_count = curr_attrs.relay1_count || 0;
// 判断上一次记录的日期,如果不是今天,则清零
if (curr_attrs.relay1_date !== Cloud.Utils.dateFormat("YYYY-MM-DD")) {
relay1_count = 0;
}
// 本次计数+1
push_attributes.relay1_count = relay1_count + 1;
// 记录今天日期
push_attributes.relay1_date = Cloud.Utils.dateFormat("YYYY-MM-DD");
}
return push_attributes;
}
示例:自动下发服务器时间
某设备端需要在收到平台下发继电器开关动作时,同时下发服务器的时间。我们可以在预处理函数中这样写:
module.exports = function (push_attributes) {
if (push_attributes.relay1 !== undefined) {
push_attributes.relay1_time = Cloud.Utils.dateFormat("YYYY-MM-DD HH:mm:ss");
}
return push_attributes;
}
这样一来,当我们在 ThingsCloud 控制台或用户应用 ThingsX App 中下发继电器开关量时,经过该属性下发预处理函数的处理,设备端实际收到的 JSON 消息,例如:
{
"relay1": true,
"relay1_time": "2023-12-03 15:25:32"
}
以上云函数中用到内置函数 Cloud.Utils.dateFormat
。
ThingsCloud 还支持完善的时区设置,假设这里使用 美国东部时区 来生成日期时间,修改如下:
module.exports = function (push_attributes) {
// 在函数开头设置时区
Cloud.Utils.setTimezone("America/New_York");
if (push_attributes.relay1 !== undefined) {
push_attributes.relay1_time = Cloud.Utils.dateFormat("YYYY-MM-DD HH:mm:ss");
}
return push_attributes;
}