ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Spring Boot智慧大棚管理系统:温湿度监控与自动调温实现解析

Spring Boot智慧大棚管理系统:温湿度监控与自动调温实现解析 1. 项目到底解决什么问题1.1 传统大棚管理的痛点蔬菜大棚种植最讲究一个环境稳定。就拿番茄来说白天最适温度一般在25℃左右夜间还要降一些温度一旦连续超过33℃坐果率就会明显下降要是低于10℃根系吸收养分受阻植株长势变差。过去农户一天要跑好几次大棚靠手背感觉温度、看温度计读数再跑回去拉卷帘、开风口不仅费人力而且存在滞后性。半夜气温骤降要是没人起来盖草帘一棚苗可能就冻坏了。这个项目的出发点就是把这些人工判断和操作变成自动化的闭环传感器持续采集温度系统根据预设策略自动控制风机、湿帘、加热器、卷帘这类设备让大棚环境尽量维持在最适区间。1.2 系统能做什么这套系统我拿到手仔细看过它不是一个简单的温度显示页面而是一个完整的管理平台。后台可以维护多个大棚信息比如大棚编号、位置、种植品种每个大棚下挂接温湿度传感器。首页有当前温度实时展示和历史曲线点击某个大棚就能看到最近24小时温度走势。核心的调温功能支持手动和自动两种模式手动模式下管理员在页面上远程开启风机或加热器自动模式下系统定时读取温度数据按预先设置的区间判断一旦超限就自动打开对应降温或升温设备并生成控制日志。除此之外系统还有报警功能温度越限时会生成报警记录提醒管理员及时处理。这种设计既适合单个大棚的精细化控制也能扩展到几十个大棚的统一管理。1.3 适合哪些人拿来学习我为什么推荐这个项目作为学习素材因为它麻雀虽小五脏俱全。对正在准备Java课程设计或毕业设计的同学来说它覆盖了从需求分析、数据库设计、后端接口到前端页面展示的完整流程对刚学完Spring Boot想找项目练手的人它比单纯做用户管理系统有意思得多涉及的不是简单CRUD还有定时任务、状态设计、规则判断这些真实业务逻辑。即使是对智慧农业方向感兴趣的开发者也能从这个项目里提取设备控制的通用思路后面接上真实传感器和继电器就能改造成可落地的产品。另外项目配套提供的文档和运行演示视频对初学者非常友好照着视频先把效果看明白再回头看代码学习效率和信心都会高很多。2. 整体技术架构与模块拆解2.1 为什么非选Spring Boot不可现在做Java Web项目Spring Boot基本是标配了。它最让人舒服的一点是把原本SSM时代一堆繁琐的XML配置全部交给了自动装配内嵌Tomcat也让部署变得异常轻松直接java -jar就能跑。对于大棚管理这种单体应用不需要微服务那套复杂的东西一个Spring Boot应用加一个MySQL数据库既能快速开发又方便后期维护。而且它生态成熟无论是MyBatis-Plus、Spring Security还是ECharts数据展示都能找到大量现成的集成方案。面试时别人也总问Spring Boot核心自动配置原理是什么如果你亲手搭过这类完整项目看到那些spring.factories和ConditionalOnClass注解的时候理解起来比背八股文容易得多。2.2 系统模块划分我按自己拆解项目的习惯把这个系统分成了六个模块用户与权限模块负责登录、登出和用户角色管理普通用户和管理员看到的功能不一样。大棚信息模块维护大棚的基础档案包括大棚名称、面积、种植品种、所在位置。传感器管理模块管理温湿度传感器编号、所属大棚、安装位置、在线状态。环境数据模块定时采集各传感器的温湿度保存温度历史记录供图表展示。设备控制模块管理风机、湿帘、加热器、卷帘这些执行设备提供手动控制和自动控制两种入口。报警与日志模块生成温度越限报警记录所有操作和设备动作方便追溯。这种模块划分是对着需求文档和数据库表慢慢整理出来的。做这类系统最忌讳上来就写代码先花一小时把模块边界和表关系理清后面开发就是往格子里面填内容而已。2.3 前后端交互方式这个项目的前端和后端采用分离模式。Spring Boot只负责提供RESTful API前端是一个独立的Vue项目通过axios调用后端接口再用ECharts渲染温度曲线。也有版本直接使用Thymeleaf服务端渲染页面和后端混在一起。两种方式我对比过前后端分离结构清楚再做App或者小程序可以直接复用APIThymeleaf则胜在部署简单不用额外起一个前端服务。如果是学习目的我更推荐前后端分离因为能顺带把vue-element-admin这类脚手架捋一遍对以后进公司做全栈项目非常有帮助。交互流程上浏览器发送HTTP请求到ControllerController调用Service处理业务Service通过Mapper操作数据库最后把结果封装成统一的Result对象返回给前端前端根据code字段判断成功还是失败。我在代码里看到项目对返回格式也做了规范这个是很多学生项目容易忽略的点。3. 智能调温的核心逻辑与实操实现3.1 温度采集与数据模型别忽略单位换算智能调温的第一步是拿到准确可靠的温度数据。真实大棚里一般用DS18B20这类数字温度传感器配合单片机通过串口或无线模块把温度值传到服务端。但这个项目为了演示方便用的是模拟数据一个定时任务每隔一分钟为每个启用的传感器生成一条温度记录模拟值在设定范围内随机波动。这种方式虽然没有真实硬件那么刺激但好处是你不需要任何额外设备就能跑通完整流程后续接真实数据源只需要替换数据采集那一层。设计温度记录表的时候我在代码里看到它用一个字段存温度、一个字段存湿度时间字段精确到秒。这里有个小提醒温度值建议用decimal(5,1)而不是double原因是double在数据库里容易产生0.30000000000000004这类精度问题而decimal能保证显示和运算都稳定。如果后面要对接硬件还需要加一个采集时间字段和传感器编号索引方便按时间范围查询。3.2 调温规则引擎设计别让设备频繁启停这是整个系统最核心的部分也是面试时最值得拿出来讲的点。简单的做法是当前温度大于上限就开风机小于下限就开加热器。但如果直接这么写实际用起来会有个问题温度在上限附近抖动时风机会开了又关、关了又开继电器触点很快就寿命耗尽。我在这套项目里看到它的处理方法是引入了滞回区间用两个阈值控制启动和停止。比如目标温度区间是20~25℃那么当温度升到26℃时开启降温设备等温度降到24℃时才关闭当温度降到19℃时开启加热器升到21℃时关闭。这样中间就有一个缓冲带设备不会因为微小波动频繁切换。这个规则没有用复杂的规则引擎就是在一个专门的Service类里用条件判断实现但代码结构上做到了可配置每个大棚可以独立设置上下限、停止阈值和启停标志逻辑清晰维护起来不费劲。3.3 设备联动控制流程一次完整的自动调温流程是这样的定时任务触发后系统先查出所有处于自动模式且启用了调温的大棚然后逐个读取该大棚最新温度与配置的阈值比较。如果触发了降温条件就检查对应的风机、湿帘设备是否已经开启如果没开就调用设备控制服务向设备发送开启指令同时将设备状态更新到数据库。控制指令在演示项目里可能只是日志记录但真实项目里往往会通过串口或者MQTT协议把消息发给下位机由下位机控制继电器通断。整个联动过程涉及的核心语句是对设备状态和温度条件的双重判断避免重复下发指令。我翻代码的时候特别注意了这一点如果是新手写的版本很容易在每个定时周期里都发一次打开风机指令这样既浪费网络也会让设备动作混乱。3.4 用定时任务实现无人值守自动调温要无人值守主要靠Spring Task。在启动类或者配置类上加上EnableScheduling然后在一个方法上标注Scheduled(cron 0 0/1 * * * ?)表示每分钟执行一次扫描任务。这里有一个我实际踩过的坑如果项目里存在多个定时任务要小心它们共用的线程池。默认情况下Spring Task的调度线程池只有一个线程一旦某个任务执行时间过长其他任务就得排队等待表现就是温度数据迟迟不更新。解决方法是给线程池增加核心线程数或者在配置文件中设置spring.task.scheduling.pool.size5。另外定时扫描调温虽然简单但如果未来系统要部署多个实例做负载均衡同一时刻多个实例都会执行定时任务可能造成设备重复控制。这种场景就需要引入分布式锁学生项目不需要但面试提到这个点会很加分。4. 数据库设计与关键代码解析4.1 数据表结构数据库设计决定了这个项目能走多远。我盘点了一下核心表大概有这些表名关键字段作用userid, username, password, role系统用户greenhouseid, name, location, area, crop_type大棚基本信息sensorid, greenhouse_id, sensor_type, status传感器管理temperature_logid, greenhouse_id, temperature, humidity, create_time温湿度历史记录deviceid, greenhouse_id, device_name, device_type, status执行设备信息control_logid, device_id, action, temperature, create_time设备控制记录alarm_logid, greenhouse_id, alarm_type, message, is_handled, create_time报警记录从字段命名可以看出表之间通过逻辑外键关联比如sensor表通过greenhouse_id关联到greenhousetemperature_log又是按大棚落数据。这样查询某个大棚的历史温度非常方便。有一点需要注意环境数据表会随着时间快速增长如果预计要存几年数据并且大棚数量很多建议在create_time字段上建索引同时定期归档或清理三个月前的历史记录。项目里虽然没做自动清理但数据表的预留字段和索引设计都考虑到了这个方向。4.2 MyBatis-Plus集成与分页项目持久层用的是MyBatis-Plus它对MyBatis的增强确实省了很多重复劳动。集成方式很简单pom.xml引入com.baomidou:mybatis-plus-boot-starter然后在application.yml中配置mapper-locations指向XML文件目录并把map-underscore-to-camel-case设为true这样数据库的create_time字段就能自动映射到实体类的createTime属性。分页这块我特别提醒一下不要自己在SQL里手写limit既要考虑页码从0还是1开始又要应对不同数据库的方言差异。MyBatis-Plus提供了分页插件配置一个PaginationInterceptor后只需用Page 对象作为Mapper方法参数插件就会在查询时自动拼接limit语句。代码里我看到它对前端传过来的分页参数做了统一的pageNum和pageSize接收返回的数据也带上了总记录数前端表格可以直接使用。4.3 控制接口实现示例设备控制是整个系统交互的核心接口。这里我贴一段简化后的Controller代码方便大家感受项目风格RestController RequestMapping(/api/device) public class DeviceController { Autowired private DeviceService deviceService; PostMapping(/control) public Result control(RequestBody ControlRequest request) { // 校验设备编号是否存在 Device device deviceService.getById(request.getDeviceId()); if (device null) { return Result.error(设备不存在); } // 手动控制ON表示开启OFF表示关闭 if (ON.equals(request.getAction())) { deviceService.turnOn(device); } else if (OFF.equals(request.getAction())) { deviceService.turnOff(device); } // 记录控制日志 deviceService.recordControlLog(device, request.getAction()); return Result.success(设备控制成功); } }这段代码看起来简单但里面有几个工程细节值得学习。首先是请求封装成ControlRequest对象而不是写两个字符串参数这样后面扩展验证码或者备注字段时不用改方法签名其次是控制动作和设备状态更新都落在Service层Controller只负责参数接收和结果返回最后是每次控制都会记录日志方便审计和问题定位。实际项目中还会在控制前再查一次用户权限防止非管理员操作设备。4.4 记录日志与报警温度越限报警在设计上也有讲究。项目里报警分两级一级是温和提醒比如温度超过设定值但没超过危险值这时候只需要在报警页面生成一条记录另一级是紧急报警比如温度超过40℃或者低于5℃这时候除了生成记录还要真正通知管理员。通知方式最常见的是短信国内一般通过阿里云短信服务发送模板消息但演示代码里通常只是把报警消息写入日志表毕竟短信需要申请签名和模板。为了避免发短信接口响应慢把主流程卡住我看到有用Async注解把发送逻辑丢到独立线程执行的做法这个思路值得借鉴。如果你要二次开发可以再接入邮件或者企业微信机器人通知成本更低体验也不错。5. 从拿到项目到成功运行部署全流程5.1 环境准备拿到的这个项目是完整的工程第一步肯定是先把环境准备好。JDK建议用1.8如果项目用的Spring Boot 2.3.xJDK8完全够用而且兼容性最好如果你电脑装了JDK17最好留意一下pom.xml里的版本配置很多旧项目用JDK17启动会报一些奇怪的反射异常。开发工具IDEA就行要确保装好Lombok插件这个项目大量使用了Getter/Setter这类注解没装插件编译直接报找不到方法。接下来是MavenIDEA自带Maven但国内下载依赖很慢建议在settings.xml里配置阿里云镜像不然光下载依赖就要等半天。MySQL我建议用5.7如果装了8.0也能跑但注意驱动版本和时区配置。5.2 导入项目与配置修改导入方式很简单IDEA里选择File - Open选中项目的pom.xml以Maven项目方式打开等依赖自动下载完成。然后找到src/main/resources/application.yml修改数据库连接信息。这里给出一个基本配置示例server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/greenhouse?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true如果你用的是MySQL 8.xdriver-class-name得是com.mysql.cj.jdbc.Driver5.x则用com.mysql.jdbc.Driver。url末尾的serverTimezoneAsia/Shanghai是为了避免时区导致的日期显示问题少这一行通常会报连接数据库超时。5.3 数据库初始化项目里通常会附带一个.sql脚本比如greenhouse.sql。执行前先手动创建一个数据库注意字符集选utf8mb4不然中文容易乱码。然后用命令行或者Navicat导入脚本。导入完成后打开脚本看一眼里面是否有初始管理员的数据一般会直接插入一条admin记录密码可能是明文或者BCrypt加密后的密文。如果你登录不进去要么是没有初始数据要么是密码格式不对可以到数据库里手动改一条记录密文可以从项目源码中的测试类里复制。5.4 启动与验证所有配置完成后找到启动类类名一般类似于GreenhouseApplication右键运行main方法。看到Started GreenhouseApplication in xx seconds说明启动成功了。浏览器访问http://localhost:8080跳转到登录页。输入初始账号密码进入系统后先看看温度曲线页面有没有数据如果没有说明定时任务还没到执行时间等一两分钟刷新即可。接着去设备页面手动开关一下风机观察控制日志是否生成。最后可以尝试把某个大棚的温度上限临时调低模拟温度超限看看报警记录会不会出现。验证完这一套整个项目的运行链路就摸透了。6. 常见问题排查与避坑指南6.1 启动报错类问题这类问题出现频率最高我整理一个速查表现象常见原因解决办法8080端口被占用本机其他服务占用了端口修改server.port为8000或8081数据库连接拒绝MySQL没启动或密码不对检查MySQL服务检查配置文件账号密码找不到主类或驱动类依赖没下载完整或版本不匹配Maven重新导入检查pom.xml版本Invalid bound statementMyBatis的mapper.xml没被扫描检查mapper-locations路径是否与XML目录一致登录报401或404Security配置拦截了登录接口在安全配置中放行/login和静态资源路径我个人的习惯是启动前先不急着点运行先在命令行执行mvn clean install如果这个能通过说明代码和依赖基本没问题启动失败的原因大概率集中在数据库和端口这些外部环境。6.2 功能异常排查运行起来之后更常见的是一些看起来能用但又不完全对的诡异问题。最常见的是定时任务不执行这时候先看启动类有没有EnableScheduling注解再看定时方法所在的类有没有被Spring扫描最后看日志里有没有报错。温度数据有了但设备不联动要分三步排查先看当前温度是否真的超过了配置阈值再看设备状态是否被置为自动模式最后查控制日志里是否已经下发过指令。如果页面能显示数据但报错跨域别怀疑是后端写错了而是浏览器的同源策略拦截需要在后端配置跨域过滤器或者在Vue项目的vue.config.js里设置代理。6.3 二次开发的3个建议最后分享三个我认为对这个项目最有价值的改造方向。第一把规则引擎从Service里独立出来定义一个Rule接口每种调温策略一个实现类再通过工厂类按大棚类型或者季节选择不同策略这样既能支持夏季降温策略和冬季保温策略又不会把一堆if else塞在一个方法里。第二温度调节算法可以再升级一步引入PID控制思想传统区间控制的问题是降温设备全开或全关环境波动大PID可以根据温差大小调节设备开启台数或占空比对实际种植环境更友好。第三如果想接真实硬件后端可以集成EMQX这类MQTT消息服务器设备通过主题订阅控制指令传感器通过上报主题回传温度替换掉模拟数据的定时任务项目就能真正落地到大棚里。我个人做这个项目最大的体会是不要贪多求全。很多人拿到源码第一件事是去跑起来但真正跑起来之后呢如果没有把调温那个核心模块的逻辑吃透不懂为什么用滞回区间、为什么定时任务要控制并发那到最后写答辩论文或者面试讲项目的时候还是会卡壳。建议大家用“先跑通、再断点、后重构”三步来学习先把系统跑起来感受功能再在调温判断的那个类上打几个断点看看温度和设备状态是怎么变化的最后尝试把某一块逻辑自己重写一遍比如把固定阈值改成可配置的数据库表这个过程比看十遍视频都有用。
返回列表