17-自动化阈值控制:温湿度超标自动通风、自动浇水业务逻辑
各位看官,前几篇我们把传感器数据从 485 总线一路搬到了云端时序数据库,属于"只读不写"的活儿。可智慧农业的核心诉求从来不是"看得见",而是"管得住"——大夏天的棚里 38℃,你光在手机上看个数字,菜就熟过头了。今天这篇,就来把自动化控制这块硬骨头啃下来。
一、需求拆解:控制到底要解决什么问题
先说三个最典型的场景:
- 温度过高自动通风:大棚中午暴晒,温度传感器上报 38℃,阈值设定 35℃,系统自动开启卷膜电机/风机,降温后自动关闭。
- 土壤湿度低自动浇水:土壤湿度低于 25% 时自动打开电磁阀滴灌,湿度回到 45% 后停水。
- 光照不足自动补光:阴雨天光照强度低于 8000Lux,自动开启补光灯,持续 2 小时。
你看,这些需求长得很像:传感器数值 + 阈值比较 + 触发执行器。这就是"阈值规则"的本质。它不需要复杂的机器学习,一套规则引擎就能吃得下。但别小看它,落地时全是细节:什么时候触发、动作执行多久、触发了要不要防抖、人手干预了规则还该不该管。
二、阈值规则引擎:两张表打天下
规则引擎的设计核心,是把"条件"和"动作"解耦,做成可配置的规则表。数据库里就两张表:
规则表 rule
├── id
├── name 规则名称,如"高温通风"
├── sensor_point 条件传感器点位,如 temp_1
├── operator 比较符,如 gt / lt / gte / lte
├── threshold 阈值,如 35.0
├── time_start 生效时间窗开始,如 08:00
├── time_end 生效时间窗结束,如 18:00
├── enabled 是否启用
└── action_id 关联动作
动作表 action
├── id
├── device_point 执行器点位,如 fan_1(风机继电器)
├── action_value 动作值,如 1(开)或 0(关)
├── duration_sec 执行时长,如 300 秒
└── cooldown_sec 冷却时间,如 600 秒
两张表一拼,规则就活了:"当 temp_1 > 35.0(且当前时间在 08:00-18:00 内),则 fan_1 置 1,持续 300 秒"。生效时间窗这个字段别忽略,夜里你开着卷膜电机,凌晨的露水能把作物全冻死,这是踩坑踩出来的。
三、条件模型与动作模型:把业务翻译成结构
新手最容易犯的错,是把判断逻辑写死在代码里——加一条规则就改一次代码、发一次版。正确姿势是把"业务知识"抽成数据,程序只做通用执行。
规则条件模型(Condition)设计成这样:
| 字段 | 含义 | 示例 |
|---|---|---|
| pointCode | 传感器点位编码 | soil_humidity_1 |
| compare | 比较符 | > < >= <= |
| threshold | 阈值 | 25.0 |
| timeWindowStart/End | 生效时间窗 | 08:00 ~ 20:00 |
| windowType | 窗口类型:每天/仅白天/关闭 | DAILY |
动作模型(Action)设计成这样:
| 字段 | 含义 | 示例 |
|---|---|---|
| pointCode | 执行器点位编码 | valve_1 |
| actionValue | 动作值,继电器通断 | 1 / 0 |
| durationSec | 执行时长,超时自动复位 | 600 |
| cooldownSec | 冷却时间,防抖用 | 1200 |
这里有个关键点:动作值要写入 Modbus 线圈还是寄存器? 卷膜电机这种开关型设备走 FC05 写单线圈;变频器调风速这种模拟量设备走 FC06 写单寄存器。点位模型里要带 functionCode 字段,动作执行时才知道调哪种报文。
四、规则引擎实现:定时扫描 + 触发执行
引擎跑起来就是一个定时任务,默认 30 秒扫一轮,流程如下:
- 取数据:从内存缓存(边缘网关实时上报的数据)读传感器最新值。
- 过条件:逐条规则比较,加上生效时间窗校验。不满足直接跳过。
- 查状态机:每条规则有个"上次触发时间",在冷却期内不重复触发——防止温度在阈值附近抖动,风机开一下停一下。
- 下动作:通过 Modbus TCP 写执行器,同时记录一条执行日志(触发规则、动作值、时间)。
- 超时复位:动作执行满 durationSec 后,自动把执行器恢复到默认值(比如关风机)。
SpringBoot 里核心就三个类:RuleEntity(规则)、ActionEntity(动作)、RuleEngineService(引擎调度)。我直接贴核心执行逻辑:
@Service
public class RuleEngineService {
@Autowired
private PointDataCache pointCache; // 最近一次点位数据缓存
@Autowired
private ModbusMasterService modbus; // Modbus 写操作封装
@Autowired
private RuleRepository ruleRepo;
private final Map<Long, Long> lastTriggerMap = new ConcurrentHashMap<>();
@Scheduled(fixedDelay = 30000) // 每 30 秒扫描一次
public void scan() {
for (RuleEntity rule : ruleRepo.findByEnabled(true)) {
// 1. 生效时间窗校验
if (!inTimeWindow(rule)) continue;
// 2. 冷却期校验
long now = System.currentTimeMillis();
Long last = lastTriggerMap.get(rule.getId());
if (last != null && now - last < rule.getAction().getCooldownSec() * 1000L) continue;
// 3. 比较阈值
Double cur = pointCache.getLatest(rule.getSensorPoint());
if (cur == null) continue;
if (!compare(cur, rule.getOperator(), rule.getThreshold())) continue;
// 4. 触发动作:写执行器
doAction(rule.getAction());
lastTriggerMap.put(rule.getId(), now);
ruleLogRepo.save(buildLog(rule, cur));
}
}
private void doAction(ActionEntity action) {
// functionCode=5 写线圈 / 6 写寄存器,发 Modbus 报文
modbus.writePoint(action.getPointCode(), action.getActionValue());
// 5. 注册超时复位任务
scheduleReset(action, action.getDurationSec());
}
}
注意 scheduleReset:用 ScheduledExecutorService 延迟执行,到点把执行器写回默认值。千万别省这步,否则风机开了忘了关,棚里一夜变冰窖。
五、自动浇水完整业务流程拆解
把上面拼起来,走一遍"自动浇水"全流程,你就彻底懂了:
- 数据层:土壤湿度探头(485 总线)→ 边缘网关采集,土壤湿度 24.8%。
- 缓存层:网关解析报文,湿度值写入本地缓存,同时 MQTT 上报云端。
- 规则层:云端规则引擎扫描,命中规则"soil_humidity_1 <= 25.0",生效时间窗通过,冷却期已过。
- 动作层:引擎调用 Modbus TCP 写
valve_1线圈为 1,电磁阀打开,滴灌开始。 - 闭环:湿度回升到 32%(阈值带 25/45 之间),此时不满足"<=25"这条条件,但注意——我们还有一条规则"soil_humidity_1 >= 45.0 → valve_1 写 0",等湿度够高才停水。
- 超时兜底:哪怕规则没触发,valve 打开满 30 分钟,超时复位任务强制关阀,防止管道被淹。
这里体现了一个进阶技巧:双阈值防抖。开阀阈值 25%、关阀阈值 45%,中间 25~45% 是"死区",系统不做任何操作。否则单阈值 30%,湿度在 29.9%~30.1% 抖动,阀门每分钟开合一次,电磁阀寿命撑不过一个月。
六、安全保护:农业现场不能"全自动"蛮干
自动化的反面是"失控"。三把保护锁必须上齐:
- 双阈值 + 死区:见上文,避免频繁启停,保护执行器和作物。
- 手动优先:云端下发"手动控制"指令后,规则引擎对该点位自动挂起(
manualOverride标志),执行器只听手动的。手动解除后才能恢复自动化。你总不能大棚里有人作业时,系统突然把卷膜机降下来。 - 执行次数限制 + 异常回滚:单条规则 1 小时内触发上限(比如 5 次),达到上限告警并禁用规则。Modbus 写失败重试 3 次仍失败,走告警通道通知管理员,绝不静默失败。
七、小结
阈值自动化控制,业务上就一句话:传感器值过条件,执行器动一动。但工程上它把数据采集、点位模型、Modbus 写报文、定时任务、状态机、安全兜底全串了起来。读懂这篇,你就从"只会读 Modbus"升级到了"能闭环控制设备",这在智慧农业项目里是质的飞跃。下一篇咱们聊聊多品牌 Modbus 设备怎么统一接入——那才是项目真正头疼的开始。