控制定时器
x/control/timer 组件:软PLC 定时器,支持 TON(接通延时)/ TOF(断开延时),可取消、可重触发。协议无关,常与 x/iotRead / x/iotWrite 串接实现延时动作逻辑;每条输入消息求值一次,结果布尔量写入指定 metadata 键。
需要额外引入扩展库:rulego-components-iot (opens new window)
# 配置
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mode | string | 是 | 定时器模式:TON(接通延时,输入持续为 true 达预设时间后输出 true)/ TOF(断开延时,输入持续为 false 达预设时间后输出 false) |
| pt | string | 是 | 预设时长(计时时长):输入保持满足达到此时长时定时器提交——TON 输出置 true、TOF 输出置 false,并向下游补发一条携带新输出的消息;计时期间输入反向则取消。如 3s、500ms,支持 ${metadata.xx} |
| in | string | 否 | 布尔输入模板,如 ${metadata.start};留空则取 msg.Data 原始值判真假 |
| out | string | 否 | 输出布尔量写入的 metadata 键,默认 q |
# 输出
- 结果布尔量写入
metadata[out](默认metadata.q),消息透传至下游节点。 - TON:输入 false→true 开始计时,持续
pt后置 true;计时期间输入提前变 false 则取消、输出复位。 - TOF:输入 true→false 开始计时,持续
pt后置 false;计时期间输入提前变 true 则取消。
# 消息与规则链行为
- 一次成功计时,下游收到 2 条:触发沿那条(如 TON 上升沿,
q=false,表示"计时中、输出仍为 false")+ 到点提交那条(q=true,由内部闹钟经全新 ctx 补发,表示"计时满、输出置位")。 - 取消不阻塞规则链:取消只是作废内部闹钟(代次失配后闹钟静默返回),不影响业务消息透传与规则链收尾;
OnEnd/OnAllNodeCompleted照常对业务消息触发。
# Relation Type
- Success: 执行成功,把消息发送到
Success链。 - Failure: 执行失败,把消息发送到
Failure链。
# 示例
{
"ruleChain": {
"id": "timer_demo",
"name": "电机延时启动",
"root": true,
"debugMode": false
},
"metadata": {
"firstNodeIndex": 0,
"nodes": [
{
"type": "x/control/timer",
"name": "3 秒延时启动",
"debugMode": false,
"configuration": {
"mode": "TON",
"pt": "3s",
"in": "${metadata.start}",
"out": "q"
}
}
],
"connections": []
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 完整场景:电机延时启动(可取消)
工艺: 按下启动按钮后延时 3 秒才起电机(给润滑/预热留时间);3 秒内松开按钮或拍下急停,则取消启动。
为什么用 timer 而不是内置 delay: delay 会把“按下”消息延迟 3 秒后照发——即使中途松手,电机仍会误启动(危险)。timer 在输入出现反向边沿时取消计时,松手即停。
{
"ruleChain": {"id": "motor-delay-start", "name": "电机延时启动", "root": true},
"metadata": {
"endpoints": [
{
"id": "scan", "type": "endpoint/schedule", "name": "周期扫描",
"routers": [
{"from": {"path": "*/1 * * * * *"}, "to": {"path": "motor-delay-start:read"}}
]
}
],
"nodes": [
{"id": "read", "type": "x/iotRead", "configuration": {
"driver": "s7", "server": "192.168.1.10:102",
"points": [{"name": "start", "addr": "DB1.DBX0.0", "type": "BOOL"}]
}},
{"id": "flat", "type": "jsTransform", "configuration": {
"jsScript": "var d=JSON.parse(msg.data||'[]');var o={};d.forEach(function(p){if(!p.error)o[p.name]=p.value;});metadata.start=o['start'];msg.data=JSON.stringify(o);return {msg:msg,metadata:metadata,msgType:msgType};"
}},
{"id": "t", "type": "x/control/timer", "configuration": {
"mode": "TON", "pt": "3s", "in": "${metadata.start}", "out": "q"
}},
{"id": "write", "type": "x/iotWrite", "configuration": {
"driver": "s7", "server": "192.168.1.10:102",
"points": [{"name": "motor", "addr": "Q0.0", "type": "BOOL", "value": "${metadata.q}"}]
}}
],
"connections": [
{"fromId": "read", "toId": "flat", "type": "Success"},
{"fromId": "flat", "toId": "t", "type": "Success"},
{"fromId": "t", "toId": "write", "type": "Success"}
]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
flat节点把x/iotRead的点位数组[{name,value}]摊平,并把启动信号写入metadata.start;timer 结果写metadata.q,写节点以${metadata.q}驱动Q0.0。
时序行为:
| 时刻 | 输入 start | timer 动作 | 输出 q → Q0.0 |
|---|---|---|---|
| t=0 按下 | false→true | 上升沿,武装 3s 闹钟(gen++) | false(未启) |
| t=0~3s 按住 | true | 无新边沿,继续计时 | false |
| t=3s 仍按住 | true | 闹钟到期,提交 | true → 电机启动 |
| 若 t=2s 松手 | true→false | 下降沿,gen++ 作废旧闹钟 | false → 永不启动(取消) |
| 取消后再按 | false→true | 新上升沿,重新武装 3s | false(重新计时) |
更多组合示例见:IoT 场景示例 · 软PLC式逻辑控制
在 GitHub 上编辑此页 (opens new window)
上次更新: 2026/07/29, 10:24:31