
简介这份智慧农业集成管理系统源码包面向农业信息化从业者、Java开发者及农业物联网技术学习者提供一套涵盖物联网监测、大数据分析、AI病虫害预警、GIS地块管理、自动化设备控制等模块的完整工程实现。压缩包共224个文件以142个Java源文件为核心搭配30个HTML页面、25个XML配置、20个JavaScript脚本及2个样式表还有1份SQL数据库脚本整体仅476KB。各类型文件分工明确可直接导入开发环境运行调试便于理解智慧农业平台从后端逻辑、前端交互到数据存储的全链路设计。源码目录按功能模块拆分覆盖传感器数据采集、设备远程控制、地块信息管理等典型业务场景检索与学习都较为直接方便。目前已有174人学习下载对于希望快速上手农业信息化项目或借此扩展物联网、大数据应用开发能力的读者是轻量而典型的参考范例。1. 智慧农业集成管理系统把传感器、告警、大屏和远程控制装进一个工程做农业物联网项目最怕的不是没传感器而是设备和系统各说各话大棚里的温湿度数据进了数据库告警却只能发短信大屏上能看到曲线却点不了水阀换个设备厂商采集协议就得重写一遍。这套智慧农业集成管理系统思路是把“采集-存储-分析-控制-展示”做成一条完整的数据链路用一个后端服务打通设备接入、业务逻辑和前端看板适合正在做农业信息化交付、或者想把监控Demo升级成可落地系统的开发者。我拆完之后的感觉是它不炫技但边界清楚代码量适中能直接当脚手架用。2. 系统架构与数据链路从传感设备到业务面板的七个环节2.1 整体分层为什么用“设备网关 业务后端 Web大屏”三段式这套系统没有走微服务那套重型路线而是用单体应用加清晰分模块的方式组织这跟我经手的大多数农业项目是匹配的——园区规模几十个传感器、十几个控制设备单体部署成本低维护的人也不需要懂分布式。架构上分为三层设备接入层负责接收传感器上报的数据支持轮询和主动上报两种模式业务处理层完成数据校验、阈值判断、告警生成、控制指令下发展示层提供管理后台和可视化大屏。核心的价值点是数据链路完整从设备报文到页面曲线中间不需要手工导表或写临时脚本。以下是入库链路中最关键的一段逻辑常见做法是先用统一报文结构做初步过滤public class SensorDataHandler { public void handleRawData(String deviceId, String payload) { // 1. 校验设备是否在系统中注册 Device device deviceMapper.selectById(deviceId); if (device null) { log.warn(unknown device: {}, deviceId); return; } // 2. 解析原始报文 SensorData data jsonParser.parse(payload, SensorData.class); // 3. 写入时序表 sensorRecordMapper.insert(data); // 4. 触发阈值判断 alertService.evaluate(device, data); } }这段代码的逻辑是先确认设备存在再做报文解析然后入库并触发判断。参数说明里值得注意的一点是很多项目在设备不存在时选择直接报异常但这里用日志警告后静默返回是故意保留的策略——农业现场常有网关误报或设备重启时重复上报直接抛异常容易干扰正常链路。时序数据单独建表不是和业务表混在一起。这个设计是这套系统的关键之一按天分表后查询最近一周曲线非常快统计报表也不需要全表扫描。2.2 设备管理模块型号、协议、点位配置三件套设备管理不是简单做个CRUD而是把“这个设备是什么、怎么通信、有哪些数据点位”拆成三个配置维度。系统里用一张设备表存基础信息一张协议表存通信参数一张点位表存每个数据字段的映射关系。这样换设备时不用改代码只需要在后台增加协议配置。点位配置是整个系统的核心也是新手最容易忽略的地方。比如一个空气温湿度传感器有两个数据点温度、湿度。点位表里要记录每个点的数据类型、单位、精度、报警上下限如果后续要接土壤pH传感器新增点位就行不用动表结构。以下是典型的点位映射配置结构开发时我一般直接照着这套字段建表CREATE TABLE device_point ( id BIGINT PRIMARY KEY AUTO_INCREMENT, device_id VARCHAR(64) NOT NULL COMMENT 设备编号, point_name VARCHAR(64) NOT NULL COMMENT 点位名称如temperature, point_alias VARCHAR(64) NOT NULL COMMENT 页面展示名称, unit VARCHAR(16) DEFAULT NULL COMMENT 单位, precision_value INT DEFAULT 1 COMMENT 小数位, min_value DECIMAL(10,2) DEFAULT NULL COMMENT 量程下限, max_value DECIMAL(10,2) DEFAULT NULL COMMENT 量程上限, upper_limit DECIMAL(10,2) DEFAULT NULL COMMENT 告警上限, lower_limit DECIMAL(10,2) DEFAULT NULL COMMENT 告警下限 );字段建议按实际项目调整如果接入的是脉冲计数器比如水表precision_value 直接改成0小数位没有意义如果是CO2传感器upper_limit 和 lower_limit 要注意单位是ppm还是mg/m³系统不自动换算配置错了告警就完全失真。这个表设计是我拆这套系统时印象最深的部分——它把很多项目写在代码里的硬编码抽成了数据后续维护成本会明显下降。2.3 数据存储选型MySQL加时序表还是直接用时序数据库这套系统在数据存储上用了MySQL加定时分区表的方案没有上时序数据库。选择依据很简单中小型园区场景数据量不大单个大棚每小时上报6条数据10个设备一天也就1440条MySQL完全扛得住引入时序数据库意味着增加一个服务部署和备份都更复杂。表结构上系统按天建立分区表应用层通过一个路由函数决定写入哪张表。核心逻辑是拼接表名但要注意防止SQL注入所以表名只允许数字日期格式public String getTableName(Date date) { SimpleDateFormat sdf new SimpleDateFormat(yyyyMMdd); return sensor_data_ sdf.format(date); }这个方法的含义是传入一个日期返回对应的表名。比如2025年6月1日的数据写入 sensor_data_20250601 表。这样按天分表之后删除过期数据直接 drop 整张表就行不用 DELETE 大量行。如果未来数据量涨到每天几十万条可以考虑水平拆分但绝大部分农业项目用不到。存储选型上还有一个容易忽略的点点位配置的变更要记录历史版本否则改了量程之后之前的历史数据画曲线会突然跳变排查问题时非常痛苦。3. 环境监测与告警联动阈值判断、告警分级与控制指令下发3.1 告警分级普通提醒、严重告警、设备故障三档判断逻辑告警是智慧农业系统里用户最依赖的功能之一。这套系统把告警分成三类普通提醒比如湿度略低于目标值、严重告警温度超过作物耐受上限、设备故障上报中断或数据异常。分级的意义在于后续联动策略不同——普通提醒只记录严重告警要触发控制设备动作设备故障需要通知维护人员。分级判断在代码里是一个独立方法接收点位数据和设备配置返回告警级别。以下是核心判断逻辑public AlertLevel evaluateAlert(DevicePoint point, BigDecimal value) { if (value null) { return AlertLevel.FAULT; // 数据为空视为设备故障 } if (value.compareTo(point.getUpperLimit()) 0 || value.compareTo(point.getLowerLimit()) 0) { return AlertLevel.CRITICAL; // 超限视为严重告警 } BigDecimal warnThreshold getWarnThreshold(point); // 默认5%浮动区间 if (value.compareTo(point.getUpperLimit().subtract(warnThreshold)) 0 || value.compareTo(point.getLowerLimit().add(warnThreshold)) 0) { return AlertLevel.WARNING; } return AlertLevel.NORMAL; }这段判断的意义在于区分“已经超标”和“即将超标”实际布点时根据作物类型调整摆动区间。比如叶菜类对温度波动敏感就把5%改成2%如果是仓储环境监测5%可能没必要直接按绝对值写死更干脆。设备故障判定的标准除了数据为空还可以加上“连续N次上报间隔超过设定时间”需要增加一个心跳字段。3.2 控制联动告警触发水阀/风机/卷帘的两种实现方式告警之后要能自动控制设备系统提供了两种方式规则联动和手动指令。规则联动是在后台配置“当温度大于35℃时打开风机”系统执行时调用设备控制接口手动指令则是用户在页面上直接点击按钮下发控制命令。联动配置的数据结构是一个规则表包含触发条件和执行动作。设计上没有把规则写死在代码里而是通过数据库配置这样现场调试时改阈值不用重启服务。以下是一个联动规则实例的配置逻辑INSERT INTO alert_rule (rule_name, device_point, operator, threshold, action_device, action_command, enabled) VALUES (高温通风, greenhouse_01.temperature, , 35.0, fan_01, START, 1);这条SQL的含义是当 greenhouse_01 设备的 temperature 点位值大于35时给 fan_01 设备发送 START 指令。操作符用的枚举类型支持 、、、、 五种。值得说明的是action_command 字段直接存协议指令字符串这样接入不同厂商设备时只需要改这条配置不需要动Java代码。手动控制的关键是接口设计系统里统一封装了一个控制命令下发接口。开发这种设备控制功能时有个习惯——所有指令下发都必须记录日志包括操作人、时间、指令内容、设备返回结果否则出了问题连哪个指令发错了都不知道。3.3 数据可视化的几个隐藏细节曲线粒度、时间范围与大屏特殊处理可视化大屏是验收时最容易被领导盯着的部分。这套系统的前端页面提供了两种视图管理后台的明细表格和详情曲线大屏的概览看板。曲线部分不是简单调图表库就行有几个细节直接决定好不好用。第一个细节是曲线粒度。按小时查询时如果一天显示86400秒的数据点曲线会糊成一片系统会把原始数据按5分钟或15分钟聚合。第二个细节是时间范围快捷键常见做法是提供“今日、近7天、近30天”三个快捷选项减少用户手动输入起止时间。第三个细节是大屏的特殊处理——大屏上展示的数字通常需要闪烁、变色、滚动业务后端需要提供独立的聚合接口而不是让前端拉全量明细数据自己计算。以下是聚合接口的核心思路数据量大时必须用SQL层聚合不要拉到应用层reduceGetMapping(/api/stats/trend) public ListTrendPoint getTrend(RequestParam String pointId, RequestParam String granularity) { // granularity: 5m / 1h / 1d return statisticService.queryAggregated(pointId, granularity); }这个接口的参数含义pointId 是点位编号granularity 是聚合粒度。实现时用 DATE_FORMAT(create_time, %Y-%m-%d %H:) 这样的格式化语句按小时分组5分钟粒度需要配合 FLOOR 函数做时间戳规整。性能调优上给 create_time 加索引是必须的否则时间范围一大就是全表扫描。4. Web控制台与接口设计从权限到接口鉴权的完整闭环4.1 用户权限模型管理员、操作员、只读账号三级控制这套系统的权限模型是经典的三层设计适合团队协作场景。管理员角色拥有全部功能模块权限操作员角色可以配置告警规则、下发设备控制指令只读账号只能查看数据和曲线不能进行任何配置或控制操作。权限控制的粒度在按钮级别因为查看数据的人通常也包括学校参观团队或上级领导他们只关心展示效果。后端的权限校验使用的是注解式拦截全局注册了一个拦截器在进入Controller之前完成权限判断。这么做的好处是后续接入Spring Security时可以无缝替换。Component public class AuthInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { User user (User) request.getSession().getAttribute(loginUser); if (user null) { response.setStatus(401); return false; } // 判断请求方法是否需要操作权限 String method request.getMethod(); if (POST.equals(method) || PUT.equals(method) || DELETE.equals(method)) { return user.getRole() UserRole.OPERATOR.getCode(); } return true; } }逻辑说明请求进来先检查登录态未登录直接返回401对于 POST、PUT、DELETE 这类写操作要求角色必须是操作员或管理员。这里有个实际部署时的注意点——拦截器虽然拦截了Controller层但静态资源和上传文件的访问也需要放行否则前端页面打开时会加载不到JS和CSS。4.2 接口返回格式统一包装类与错误码设计接口格式的一致性直接决定前端开发的效率。这套系统定义了一个统一返回结构所有接口都返回这个包装类包括正常数据和错误信息。格式设计上包含状态码、消息、数据三个字段。{ code: 200, message: success, data: { } }错误码设计参考了HTTP状态码的语义但做了完善200表示成功400表示参数错误401表示未登录403表示无权限500表示服务端内部错误。业务层面的错误码用四位数表达比如1001代表设备不存在1002代表点位配置错误1003代表指令下发超时。分层的错误码好处是日志检索快——线上查问题时 grep 一下错误码就能定位模块和原因。4.3 前后端联调接口文档、Mock数据与联调环境三个实践前后端分离的团队协作中这套系统采用了优先定义接口文档、再并行开发的方式。接口文档使用Swagger注解自动生成后端代码写完接口后前端可以直接在页面上调试同时后端提供了Mock数据开关在没有真实传感器时模拟设备按期发送随机数据保证前端功能开发不被硬件进度阻塞。Mock数据的核心逻辑值得直接用尤其是定时上报任务Scheduled(fixedRate 60000) public void sendMockSensorData() { if (!mockEnabled) return; Random random new Random(); double temperature 25 (random.nextDouble() * 10); // 25-35度 String payload String.format( {\temp\:\%.1f\,\humidity\:\%.1f\}, temperature, 60 random.nextDouble() * 20 ); sensorDataHandler.handleRawData(mock_dev_01, payload); }含义说明每60秒生成一组温度25到35℃、湿度60%到80%的随机数据发送给传感器处理链。这个机制在项目交付时非常有用——硬件没到位业务系统可以先给客户演示完整功能。注意两个参数fixedRate单位是毫秒模拟频率太高会刷爆表建议至少30秒以上设备编号要跟设备表里注册的一致否则走不到点位判断环节。5. 避坑指南部署与设备接入的常见问题5.1 数据库时区导致数据时间错乱现象传感器上报的数据在页面上显示的时间比实际时间早了8小时曲线整体偏移。原因MySQL连接串上没加 serverTimezone 参数JVM和数据库时区不一致。解决在数据库连接地址后面追加 serverTimezoneAsia/Shanghai并重启服务。这是拆所有Java项目都会碰到的第一道坎排查方法是在数据库执行 SELECT NOW()看看数据库时间是否正确再对比应用日志打印的时间能快速锁定问题出在哪一端。5.2 告警风暴现象某个点位触发告警后短时间内收到几十条相同告警。原因告警模块在每次数据上报时都对阈值进行判断现场设备上报频率是每10秒一次所以一分钟内同一个问题会触发6次告警。解决在告警规则中增加“冷却时间”字段同一设备同一点位在N分钟内只发送一次告警N建议设为10到15分钟。另外很多系统还做了告警升级策略——如果持续告警超过30分钟再次通知这是处理重复告警的进阶做法。5.3 控制指令下发失败但不报错现象页面上显示“指令已发送”但现场设备没有任何动作。原因下发指令后没有解析设备返回的ACK确认设备断线时指令发到了网关但无法到达终端设备。解决在后端增加指令状态确认字段设备上报时携带最后一次指令的ID只有设备端返回执行成功页面才显示成功状态。5.4 前端显示数值精度模糊现象温度显示为 25.9999999998湿度显示为 60.000000004。原因传感器原始值是浮点数在写入数据库时应用层直接用double保存没有做精度规整。解决入库前统一使用 BigDecimal 并调用 setScale(1, RoundingMode.HALF_UP) 保留一位小数如果数据库已经存了脏数据用 UPDATE 语句按字段进行清洗不要依赖前端做截断显示。5.5 大屏数据不自动刷新现象大屏挂了一天数据还是早上那个数。原因前端没有定时轮询或者轮询时间设置得太长。解决查看前端 fetch 逻辑中 setInterval 的配置大屏建议15到30秒一次管理后台曲线页面可以30到60秒一次。如果公司内部网络带宽有限不要每5秒轮询一次降低刷新频率后台接口做缓存压力会小很多。6. 二次开发技巧与验证方法让系统真正落地到某个具体园区资源拿到手之后我建议先做一次端到端验证再开始二次开发。首先启用Mock数据模式检查数据链路是否通畅其次在后台新增一个设备点位配置告警阈值确认曲线和告警均正常再次配置一条联动规则比如“温度大于30℃时打开风机”触发一次模拟数据验证执行结果。这套流程能确认系统的最小闭环。二次开发最值得优先改造的地方是通信层。原系统使用的是固定的HTTP上报接口如果接入支持MQTT的设备需要增加一个MQTT订阅模块。方法很简单引入Eclipse Paho组件在启动类中初始化客户端订阅对应主题后把收到的JSON转发给现有处理链路。有个接口是现成的——handleRawData几乎不需要修改业务代码。前端页面改造时建议保留原有布局框架只替换图表库的渲染逻辑。原有页面使用ECharts更换为其他图表库时只需要改动数据转换部分后端接口不用动。另外如果在你自己的服务器上部署需要额外配置两个东西一是开机自启动脚本系统挂了可以自动拉起二是数据库自动备份任务每天凌晨备份一次保留最近30天备份。如果做验收交付建议准备一台低配工控机4核8G足够部署完系统后连续运行72小时观察内存和CPU占用。我自己的经验是跑一周不重启、不内存溢出、不丢数据再去叫客户验收心里才有底。从那以后我每次拿到这种带管理后台和硬件联动的资源都会强制走一遍端到端验证流程——先把最小闭环跑通再谈做功能优化希望帮到你。本文还有配套的精品资源点击获取