智慧农业物联网平台源码实战:设备接入、规则引擎与二次开发要点

发布时间:2026/9/17 3:55:51
智慧农业物联网平台源码实战:设备接入、规则引擎与二次开发要点 简介长春智信创联科技有限公司出品的智慧农业物联网应用平台源码是一套基于Java Web的物联网应用系统面向农业物联网开发者、Java工程师及研究者解决农业生产环境远程监测、智能预警与可视化管控问题。包内共205个文件以14个Java源文件、15个Class、12个Jar依赖库和8个JSP页面为核心配合36个JS脚本和12个CSS完成前端交互75个GIF辅助界面呈现另含配置、文档及项目元数据压缩包仅5.08MB目录结构清晰便于导入IDE直接分析。该资源已有4972人学习/下载。平台首页展示监测数量、传感器数量、监控数量、预警信息和最近24小时温湿度变化后台通过Servlet过滤器链处理全局校验与解码结合环境温湿度、土壤成分、光照强度等数据形成从感知、预警到决策的闭环。下载后可获得可运行的工程骨架学习登录、退出、初始化等核心模块也可参考分层设计与工具类封装为二次开发或课程设计提供落地范本。1. 为什么“智慧农业物联网应用平台源码.zip”最值得先跑通的不只是界面拿到智慧农业物联网应用平台源码.zip多数人第一眼会先看大屏、看园区三维图和环境曲线。实际把它拉起来、接上几个模拟采集器之后你会意识到这个压缩包里竞争最激烈的不是图表而是设备接入协议解析、上下行报文、规则联动那几块代码决定了整个平台是“演示版”还是能拿去对真实大棚的边缘网关与卷帘控制器。成熟的智慧农业物联网源码要回答四件事传感器和网关怎么进平台、环境数据怎么统一建模、录入的阈值规则怎么自动触发动作、web 端和小程序端从哪里拿数据。它适合要给实际农田、大棚或菌菇房做环境监测与控制改造的团队也适合用 Spring Boot 和 MQTT 快速搭出完整管理端来做毕业设计或方案 demo 的开发者。2. 拆开智慧农业物联网应用平台源码模块结构、初始化和三个必改配置2.1 源码包模块分布先找到数据库脚本和配置文件拿到源码的第一件事是看目录不是看代码。常见做法是把工程拆成“接入层 服务层 前端”命名习惯类似iot-gateway、server-core、web-admin、monitor-api有时还带edge-compute这样的边缘计算子模块。先把目录摆出来后面改哪一块就清晰了。模块目录典型职责看一眼就能确认的地方iot-gateway协议接入、报文编解码、会话保活Netty 启动类、协议 handler 目录server-core用户、园区、设备、规则、报表的 Rest APIEntity/Mapper目录、接口总数web-admin后台管理和数据可视化前端package.json、路由、大屏页面applet-api小程序/移动端接口服务独立的RequestMapping前缀db或docs初始化 SQL、部署文档一批.sql文件、nginx.conf其中db下面那批 SQL 文件的价值超过前端源码设备表、产品表、物模型字典、报警历史表全在里面。先建库再启动服务避免出现“服务起来了但点开设备管理报 500”的连锁问题。建库时注意编码地块名称、传感器厂商字段都会带中文CREATE DATABASE IF NOT EXISTS smart_agri DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;utf8mb4是为了容纳生僻字和特殊字符实测有些采集器上报报文里会混入非法字符用 utf8mb4 比 utf8 更不容易在读报文时直接报字符集错误。字符集不一致的典型现场是大屏正常、打印报表乱码、导出 CSV 打开是乱码。2.2 用 Spring Boot MySQL 跑通管理后台的最短路径不看文档工程内也应该有application.yml或application-dev.yml。先把 MySQL、Redis、MQTT Broker 三个地址改成当前环境可访问的地址spring: datasource: url: jdbc:mysql://127.0.0.1:3306/smart_agri?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_mysql_password redis: host: 127.0.0.1 port: 6379 database: 0 mqtt: broker: tcp://127.0.0.1:1883 client-id: platform-server-01 default-topic-prefix: v1/prodserverTimezoneAsia/Shanghai不能省数据库里的统计数据按东八区聚合缺失时 MySQL 驱动经常把时间偏移 8 小时而大屏上的“今日平均温度”最容易暴露这个偏差。Redis 如果只做会话缓存和规则限流database: 0就够不要为了整洁把规则缓存拆到 db 15配置项一错网关心跳服务会大面积鉴权失败。数据库就绪后按依赖顺序启动两个服务。如果工程是 Maven 多模块一般先启动网关再启动服务端避免服务端启动时就想连接 MQTT 通道# 先启动设备接入服务 cd iot-gateway mvn spring-boot:run -Dspring-boot.run.profilesdev # 再启动主服务 cd server-core mvn spring-boot:run -Dspring-boot.run.profilesdev参数说明spring-boot.run.profilesdev指定加载application-dev.yml是绝大部分源码包的默认配置项。如果启动时看到端口被占用多半是设备接入服务和 API 服务共用了一个端口检查server.port是否都写成 8080。前端部分很多源码包已经带编译好的dist目录不需要再敲一遍 npm。把它挂到一个静态服务上同时把/api反代到后端即可server { listen 80; root /opt/smart-agri/web-admin/dist; location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }location /api/加不加末尾的斜杠会影响路径拼接proxy_pass写到最后一级服务地址时不要拖尾斜杠否则POST /api/v1/device/list很容易被改写成POST /api/v1/device/list/导致网关 404。2.3 跑通平台之前的三个必改点配置项常见错误值改法出错现象spring.datasource.url127.0.0.1 指向不对改成 MYSQL 容器/主机实际 IP启动即连接失败Redis 密码/端口默认空值和本地 Redis 对齐登录接口卡住、token 失效跳动mqtt.broker地址写成本机 1883 但 broker 没起换成 EMQX/Mosquitto 实际地址设备不上线网关日志刷 disconnected提示这三个参数改完管理后台的“设备列表”页面应该能正常打开。下一步才是真正把智慧农业业务跑起来让一个模拟采集器把环境数据送进平台。这三项改完管理后台基本可用。紧接着要面对的是真正的物联网接入层报警、大屏、联动都建立在设备数据能稳定进来这个前提上。3. 把大棚环境数据推进平台MQTT 主题、报文设计与设备下发通道3.1 采集链路先分层设备、边缘网关、平台的关系工程师很容易一上来就纠结“用 MQTT 还是 Modbus”。实际上智慧农业物联网应用平台里这两者都存在只是所在位置不同。传感器那侧多为 RS485/Modbus-RTU或者直接输出串口数据数据到达 4G DTU 或 ARM 边缘网关之后边缘网关负责把 RTU 转成 MQTT/HTTP/TCP 上报。平台不能替硬件供应商决定通信方式所以源码接入层往往同时保留“支持 MQTT 直连”和“支持 TCP 透传 Modbus 解码”两条链路。链路形态设备侧网关侧平台接入直连型4G 模块直接发 MQTT无MQTT Broker 规则引擎485 转发型温湿度/CO2 传感器边缘网关/DTU 做协议转换MQTT/TCP 收到标准 JSON云对接型厂家私有云平台调用第三方 Open APIHTTP webhook 拉取注意“边缘网关”这个词现在在智慧农业场景里被反复提到它的业务功能不是转发报文这么简单还要做缓存、断网续传、本地阈值快速联动比如高温立刻启动通风不等平台云处理。源码包里如果没有独立边缘程序通常也会在iot-gateway里保留一个抽象的服务接口方便后续各自实现。3.2 用 MQTT 接入的最小报文和下发命令以采集器直接走 MQTT 为例源码里的主题结构一般是“物模型 动作”两层。常见设计是这样v1/{productKey}/{deviceName}/things/event/post设备属性上报v1/{productKey}/{deviceName}/things/service/invoke平台向设备下发控制v1/{productKey}/{deviceName}/things/event/ack设备对下发的应答{productKey}、{deviceName}相当于设备在平台上的身份证源码包里这张product表和device表是核心。后台的“新建设备”操作最终都是往device表写一条记录。最简单的上报报文。用一个 mosquitto_pub 直接测平台能不能把数据解析进库mosquitto_pub -h 127.0.0.1 -p 1883 -t v1/prod/green-house-01/things/event/post -m {deviceName:green-house-01,type:env,ts:1715146000,metric:{air_temp_c:28.6,air_humidity:66,soil_moisture:42,co2_ppm:610}}参数说明-h是 broker 地址-p是 MQTT 端口-t是主题-m是报文体。ts用毫秒还是秒需要看源码里的时间戳解析大多数平台内部统一转成毫秒存datetime秒级时间戳要乘 1000 处理。如果源码里的接入服务订阅了这个主题就能在后台的“实时数据”页面看到数据同时物模型服务会把air_temp_c、air_humidity这些字段映射到设备属性表里。下行控制逻辑同理平台给设备发指令时同样走 MQTT。平台侧订阅回应可以用 paho 快速验证一整条链路import paho.mqtt.client as mqtt def on_message(client, userdata, msg): print(ftopic{msg.topic}) print(fpayload{msg.payload.decode()}) # 实际平台在这里做 ack 与规则联动 client mqtt.Client(client_iddebug-tool) client.username_pw_set(device, secret) client.on_message on_message client.connect(127.0.0.1, 1883, 60) client.subscribe(v1/prod/green-house-01/things/service/invoke, qos1) client.loop_forever()client_id 是 MQTT 协议里识别同一台设备的关键重复 client_id 会导致断连互踢这也是现场排查“设备掉线”时最先要看的一项。qos1表示至少送达一次平台侧要自己做幂等收到相同 serviceId 的指令不重复执行。没有幂等就会出现“打开水泵”指令被重发两次、结果水泵反复开关的现象。3.3 用 Modbus RTU 设备接入时的兼容处理很多智慧农业源码里还留着协议适配层专门处理 RS485 总线上的 Modbus 设备。设备地址、寄存器地址、数据类型三样对齐是接入的前提。接线调试时先用 modpoll 直接读一次寄存器确认设备能不能持续应答# 读地址为 1 的从站起始寄存器 0数量 2 modpoll -m tcp -r 0 -c 2 -t 4:float -0 -1 192.168.10.10参数说明-m tcp指定用 Modbus/TCP-r -c是起始寄存器和读取数量-t 4:float表示 4x 保持寄存器、按 float 解析-0表示对端字节序为 0这是设备厂商文档必须写明的。字节序和编码类型是最容易埋坑的地方同样的两个寄存器按 MODBUS 大端解析出来是 26.4按设备自定义小端解析就变成 0.4。接入平台时用一张寄存器映射表把平台属性与设备寄存器绑定位偏移、系数和是否带符号写在配置里而不是硬编码设备属性功能码寄存器地址数据类型缩放系数soil_temp030x0001int160.1soil_humidity030x0002uint160.1co2_ppm030x0003uint161valve_control060x0010uint161平台侧解析器把原始字节流按这张表生成长度固定的字节数组valve_control写 1 打开、写 0 关闭写指令对应 Modbus 功能码 06 预置单寄存器。源码平台通常不直接并发去轮询 485 设备而是把这个工作下沉到边缘网关平台只接收边缘网关规整后的数据。边缘网关把多个从站的数据合并在一个 MQTT 报文里还能减少网络抖动造成的数据断档。4. 资产建到地上、规则落到页面上智慧农业物联网的业务功能实现4.1 从设备表到业务厂区先把空间与设备挂上关系设备接入只是采集层管理平台的核心业务功能在大棚、地块、设备三者之间的建模关系。拿源码包里的device_product设备型号、iot_device具体设备、farm_region区域、crop_cycle种植批次来看比较成熟的建模习惯是把设备挂在“区域”下再由区域关联到一茬作物报表就能按田块分级聚合。例如一张关联表CREATE TABLE plot_device_relation ( id BIGINT PRIMARY KEY AUTO_INCREMENT, plot_id BIGINT NOT NULL COMMENT 地块ID, device_id BIGINT NOT NULL COMMENT 设备ID, position VARCHAR(64) DEFAULT COMMENT 在棚内的安装位置, status TINYINT NOT NULL DEFAULT 1 COMMENT 1-生效 0-解绑, bind_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB COMMENT地块与设备绑定关系;这个关联关系决定了业务页面的很多交互选择“3号大棚”点击一键卷帘实际是把关联到 3 号棚的所有阀门/卷帘设备取出来逐台下发set指令。如果沿用“设备只挂在用户下”的做法大屏按地块统计设备正常率、按作物统计累计用电量这些需求都会写得很别扭。源码里业务功能模块多不多、全不全看几张关系表就能判断有plot_device_relation这种表的平台往往已经考虑了“按地块看设备”“按设备看地块”的双向查询。4.2 规则引擎阈值触发、联动动作与报警落库源码的业务功能模块里规则引擎是最值得读的一块。常见实现方式是把“条件-动作”存表平台收到环境上报后把最近 N 条数据放进滚动窗口再逐个匹配规则表达式// 简化版规则命中判断实际源码里会有窗口聚合和去抖 public RuleEvalResult eval(RuleEntity rule, DeviceMetric metric) { if (!rule.isEnabled()) { return RuleEvalResult.skipped(rule.getId()); } Condition cond JsonUtil.parse(rule.getCondition()); boolean hit expressionEngine.eval(cond.getExpression(), metric); if (hit rule.getDebounceSec() 0) { return debounce(rule.getId(), rule.getDebounceSec()); } return hit ? RuleEvalResult.fired(rule.getId()) : RuleEvalResult.wait(rule.getId()); }rule.getDebounceSec()这个防抖参数不能省。智慧农业场景里土壤水分和空气温度变化慢传感器噪声又多不去抖很容易出现“今天下午 17:00 系统误报 120 次”的告警风暴。规则动作一般分三类触发继电器/变频器设备下发、生成 web 与小程序告警、把事件推送到外部 webhook。在很多源码包里这三类动作分别对应alert_record表和device_command_log表排查时顺序是“先看告警表有没有记录再看命令日志有没有下发成功”。报表页面想统计“今日告警次数”查alert_record表即可。4.3 历史数据走向大屏与云平台大数据应用开发实现大屏的“近 30 天温度曲线”和“成熟度监测指标”不要直接在大屏服务里 select 明细表。常见的做法是建一张env_statistics_hourly小时聚合表定时任务每 5 分钟把明细数据滚动聚合成每小时一行大屏和报表服务只读聚合表SELECT DATE_FORMAT(occur_time, %Y-%m-%d %H:00:00) AS stat_time, plot_id, AVG(metric_value) / 10.0 AS avg_temp, MAX(metric_value) / 10.0 AS max_temp, MIN(metric_value) / 10.0 AS min_temp FROM iot_metric_detail WHERE metric_code air_temp_c GROUP BY DATE_FORMAT(occur_time, %Y-%m-%d %H:00:00), plot_id ORDER BY stat_time DESC LIMIT 24;metric_value / 10.0是由采集端和平台的倍率约定决定很多源码包把“0.1℃”编码成整数存储查询时必须除以 10 再给前端。聚合表保证了 MySQL 在百万行数据量下大屏的刷新时间仍然能稳定在 2 秒以内。再往上走源码里往往留了转发模块对接“基于云平台大数据应用开发”的链路。把平台收到的每一条环境记录原样推给云平台数仓本地方案基本是两种数据双写本地库写一份、HTTP 转发一份或者由边缘网关直接把原始数据发到云端平台本地只接收处理后的业务数据。实现 HTTP 转发时接收方接口要约定好签名和幂等键POST /api/v1/data-forward Content-Type: application/json { requestId: f34d09f-66be-4bd2, deviceId: green-house-01, ts: 1715146000, metric: { air_temp_c: 28.6, air_humidity: 66 } }requestId在重试时必须复用同一个值接收方按这个字段去重避免数据流中间某个消费者刷新导致重复入库。很多团队把这段逻辑写死在转发服务里后面接第二个云平台时又要改代码合适做法是把 productKey 到落地接口 URL 的映射放进配置中心新增一个云平台项目就加一条配置。5. 让这套智慧农业物联网平台源码跑得稳自检、排障与三个二次开发切入点5.1 跑一个小闭环数据进库、告警落表、命令下发成功部署完成后不要急着接真机先用模拟报文把数据链路从头走到尾。这个验证只需要三步启动 mqtt 客户端发一条环境数据、查询实时数据表、用平台后台触发一次阈值告警再查告警表和命令下发日志。# 1. 确认端口在监听 ss -lnt | grep -E (:1883|:8080) # 2. 发一条测试数据 mosquitto_pub -h localhost -p 1883 \ -t v1/prod/test-01/things/event/post \ -m {deviceName:test-01,metric:{air_temp_c:35,air_humidity:70}} # 3. 确认数据已落库 mysql -uroot -p smart_agri -e \ SELECT * FROM iot_metric_detail ORDER BY id DESC LIMIT 3;如果第 3 步能查到数据说明 broker、网关解码、物模型映射、明细入库整条链路是通的。再在 web 上新建一条“温度高于 30℃ 触发告警”的规则重新上报一条 35℃ 的数据此时alert_record表应新增一条记录、device_command_log对应动作出现下发记录。这一步能定位 70% 的“页面不刷新/设备没动作”问题。5.2 排障三连日志、连接数、线程堆栈平台不稳定时先看四个指标而不是去翻代码设备接入服务的活跃连接数、Redis hit/miss、MySQL 慢查询、接口响应时间。源码包一般已经有健康检查接口适合直接打出来curl -s http://127.0.0.1:8080/actuator/health | jq .status netstat -tn 2/dev/null | grep -c :1883actuator/health返回 status 为 UP 只能说明进程活着不能说明数据链路健康所以接着用第二个命令看 broker 连接数如果 MQTT 连接数明显少于设备数通常不是网关 bug而是 clientId 重复、密钥过期或设备侧 4G 网络频繁重连。客户端掉线重连时间建议按 30 秒起步配指数退避否则现场上百个边缘网关同时重连平台网关会瞬间打满线程池。5.3 二次开发最有性价比的三个入口第一自定义协议解码器。如果现场有土壤氮磷钾传感器遵循私有总线协议第一优先级是在iot-gateway里新增自定义 decoder纳入统一的数据模型。第二对接云平台大数据应用时优先复用数据转发模块而不是另起服务双写。第三小程序端若要支持告警播报重点改alert_record表对接通知渠道的服务类。最后一个实用技巧把源码里的application-dev.yml中与业务无关的调试日志打开只把第三方 jar 包日志降到WARN然后在后台“实时数据”页面上报一条测试数据。此时日志会完整显示一条数据从 broker 进入网关、被解析、写入明细表、命中规则的全过程。如果你能在日志里看到ruleFiredtrue这条链路就彻底打通了将来排查任何设备问题先从这个日志位置切比盲目读一遍全部源码省一半时间。本文还有配套的精品资源点击获取