基于Java的智慧养猪App:物联网架构与Modbus设备接入实践
简介面向智慧农业场景的“智慧化养猪”App是一套基于Java的Android工程源码适合移动开发初学者、农业信息化从业者、物联网开发者和高校学生参考可用于毕业设计或课程实战。资源共179个文件压缩包整体约20.14MB目录结构完整38个java文件承载登录、监测、设备控制等核心业务逻辑59个xml文件负责界面布局与资源配置34个png及jpg/webp等构成应用界面素材25个so文件提供底层能力支持另有gradle构建脚本、jar依赖包和日志记录便于从工程创建到打包上线全流程研读。已有316人学习浏览可作为智慧养殖App从零搭建的入门模板。通过研究源码可掌握Android基础组件、数据交互、SDK集成与常见调试排错方法结合BaiduLBS定位库可深入理解第三方服务接入配合完整UI素材与项目配置读者能较快复现并扩展为可运行的智慧养殖演示系统。1. 智慧化养猪 App给传统猪场装上一套数字化神经一个存栏五千头的育肥场以前靠饲养员逐栏巡检、纸质记录采食和精神状态数据在纸面上睡觉。我接过的某养殖集团模拟项目X要求做一套智慧化养猪 App让场长在手机上实时查看各栋舍的温度、湿度、氨气浓度和猪只异常预警用 Java 把终端、服务端和数据链路整个跑通。这套方案解决的核心问题不是「给猪拍照」而是让养殖管理的决策从「凭经验」变成「凭数据」母猪发情漏配、育肥猪呼吸道疾病爆发、环控设备失灵引发的热应激都能在造成损失前形成预警。本文写给两类人一类是准备用 Java 技术栈做农业物联网应用的开发者想知道完整的架构和数据流怎么搭另一类是养殖企业的信息化负责人需要判断这套 App 的投入节奏和落地路径。我会把前后端分离的架构、关键数据表设计、设备接入协议、预警推送机制全部拆开讲包括几个容易让项目翻车的坑Modbus 协议字节序、4G 物联网卡在猪场的信号死角、以及 Android 端在弱网环境下的数据补传策略。这套方案不是实验室产物而是能在猪场那种灰尘大、温差大、电压不稳的环境里跑稳的生产工具。2. 为什么是 Java从猪场环境反推出来的技术选型2.1 物联网终端侧的硬约束稳定性比性能更重要猪场的硬件环境比写字楼恶劣得多配电箱电压波动常见、粉尘附着在控制柜、夏季高温高湿。我在确定技术栈时先看终端——舍内环境采集器用的大多是 Modbus RTU 协议的传感器温湿度、氨气、二氧化碳控制风机和湿帘的也是 Modbus 继电器模块。这些设备对协议栈的要求是稳定、可靠、可重试Java 的 Netty 框架处理长连接和粘包拆包非常成熟生态里还有 modbus4j 这类现成库。相比 Python 的 asyncio 方案Java 在 JVM 的稳定内存模型下跑 7x24 小时的长连接服务内存泄漏概率更低。服务端选型上我采用了 Spring Boot 搭单体应用起步等接入的设备超过五百台再拆微服务。原因是猪场项目不像互联网高并发场景单场两三百台采集器、每台 5 秒上报一条数据每秒吞吐不到 100 条消息单体应用绰绰有余。团队里如果都是 Java 背景维护成本也比引入 Go 或 Node.js 低。选型不是追新是从现场运维的角度考虑出了问题谁能最快定位、部署脚本谁都能跑。2.2 App 端与后端的数据链路三种通道各司其职智慧化养猪 App 的通信不能只靠一条链路我把它拆成了三条MQTT 通道用于实时告警和设备状态推送。终端采集器通过 4G 网关上报数据到 EMQX开源版即可Java 后端订阅 MQTT 主题把解析后的数据写入数据库。App 端同样订阅 MQTT收到告警实时弹出通知。HTTP 接口用于查询类操作比如场长查看历史曲线、猪只档案、报表导出。这部分走 Spring Boot 的 RESTful API采用 HTTPS 加密用 JWT 做鉴权。SocketTCP 长连接用于给终端设备下发控制指令比如远程开关风机、调节水帘。因为控制指令需要确认设备是否执行TCP 长连接比 MQTT QoS 更可控。三条链路共用一个后端核心服务设备接入层做了统一抽象。我在网关设备上选的是支持 MQTT 协议的 4G DTU它能自动把 Modbus RTU 转成 MQTT 消息这样 Java 端就不需要直接处理串口通信省掉一层复杂度。2.3 数据库选型时序数据与业务数据分开存储猪场的环境数据是典型的时序数据每台采集器每 5 秒报一条一天就是 17280 条一个千头猪场一天产生几十万条记录。如果全塞进 MySQL三个月后查询历史曲线会明显变慢索引膨胀得厉害。我采用双库方案MySQL存猪只档案、免疫记录、饲料消耗、人员操作日志等业务数据。这类数据量小、关系复杂适合关系型数据库管理事务。TDengine或 InfluxDB存环境采集数据、设备运行状态等时序数据按时间戳聚合查询保留原始数据只存最近 30 天超过的部分降采样成 1 分钟一条的聚合数据长期保存。这样历史曲线查询秒级返回存储压力也可控。数据库拆分后报表统计的 SQL 跨库查询是个问题。我在 Java 服务层做了一层聚合先查 TDengine 拿时序统计结果再查 MySQL 拿业务数据Java 内存里做关联组装。因为数据量不大这种服务层聚合的方式比引入数据仓库简单得多。3. 核心功能模块拆解从猪只档案到智能预警3.1 数据建模三个关键表的设计与字段释义智慧化养猪的业务核心是「猪只生命周期管理」。我设计了三个核心表下面是 MySQL 的建表 SQL-- 猪只档案表 CREATE TABLE pig_profile ( id BIGINT AUTO_INCREMENT PRIMARY KEY, ear_tag VARCHAR(32) NOT NULL COMMENT 耳标编号唯一标识, barn_id BIGINT NOT NULL COMMENT 栋舍ID, pen_id BIGINT NOT NULL COMMENT 栏位ID, breed_type VARCHAR(16) COMMENT 品种杜洛克/长白/大白, birth_date DATE COMMENT 出生日期, status TINYINT DEFAULT 0 COMMENT 0-在栏 1-转群 2-出栏 3-死亡, weight_kg DECIMAL(6,2) COMMENT 当前体重(kg), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_barn (barn_id), INDEX idx_status (status) ) ENGINEInnoDB COMMENT猪只档案表; -- 环境采集数据表TDengine 中创建 CREATE TABLE environment_data ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, device_id VARCHAR(32) NOT NULL, barn_id BIGINT NOT NULL, temperature DOUBLE COMMENT 舍内温度(℃), humidity DOUBLE COMMENT 相对湿度(%), ammonia DOUBLE COMMENT 氨气浓度(ppm), co2 DOUBLE COMMENT 二氧化碳浓度(ppm) ) TAGS (device_id, barn_id);环境数据建到 TDengine 的超级表里以 device_id 和 barn_id 作为标签查询时可以按标签快速过滤。字段设计上温度和湿度是环控的核心指标——育肥猪的适宜温度在 18~22℃湿度 60%~75%氨气浓度长期超过 25ppm 会诱发呼吸道疾病。这些阈值不写死在数据库而是配在预警规则表里可以根据季节和猪只日龄动态调整。3.2 设备接入与数据解析Modbus 协议的处理细节采集器上报的数据不是干净的 JSON而是 Modbus RTU 的寄存器数值。以温湿度传感器为例读取到的原始数据是两个 16 位寄存器值需要按照协议文档换算成实际温度。我在 Java 端封装了一个解析服务代码如下/** * Modbus RTU 温湿度数据解析 * param registerData 传感器返回的寄存器字节数组 * param dataType 1-温度 2-湿度 */ public double parseModbusData(byte[] registerData, int dataType) { // Modbus RTU 大端模式高字节在前 int rawValue ((registerData[0] 0xFF) 8) | (registerData[1] 0xFF); // 温度传感器原始值除以10得到实际温度支持负数 if (dataType 1) { // 处理负数Modbus 用补码表示负数 if (rawValue 0x8000) { rawValue rawValue - 0x10000; } return rawValue / 10.0; } // 湿度传感器部分设备直接返回百分比部分需要除以10 return rawValue / 10.0; }真正让新人踩坑的是字节序问题。不同厂家传感器的 Modbus 寄存器有的大端、有的小端有的浮点数用两个寄存器按 IEEE 754 存储。我在接入某品牌氨气传感器时就遇到了字节序反了导致浓度显示成天文数字的情况。解决办法是对接入的每一款设备先用手持 Modbus 调试工具读原始值确认字节序和数据精度然后在设备配置表里加上 byteOrder 和 precision 两个字段解析服务根据设备型号动态读取配置。3.3 预警引擎规则可配置推送要分级预警是智慧化养猪 App 最有价值的功能。不能在环境数据超标时无脑告警否则饲养员一天收几百条推送很快就把通知关掉。我把预警规则设计成三级一级预警黄色温度超过设定阈值 2℃或者氨气超过 20ppmApp 推送提醒。二级预警橙色温度超过阈值 5℃持续 10 分钟以上或湿度超过 80%推送 短信通知场长。三级预警红色设备离线超过 15 分钟或温度超过阈值 8℃推送 短信 电话语音通知立即触发应急预案。预警规则表记录了规则的条件表达式用 Java 的 Aviator 表达式引擎做规则评估支持场长在界面上自行调整阈值。推送通道上因为 Android App 常驻后台可能被系统杀掉我除了用极光推送之外还保留了一个 WebSocket 通道做前台消息实时到达后台被杀之后依赖厂商推送通道拉起。4. App 端到 Java 后端接口设计与联调血泪经验4.1 数据上报接口批量上报与合并去重App 端有移动巡检功能饲养员携带手机在猪舍内扫描耳标、录入猪只异常情况。巡检数据需要支持离线保存、联网上报。后端接口设计成批量提交模式一次最多传 50 条巡检记录PostMapping(/api/pig/inspection/batch) public ApiResponseInteger batchInspection(RequestBody Validated ListInspectionDTO list) { // 参数校验单次请求数量限制 if (list.size() 50) { return ApiResponse.error(400, 单次批量提交不能超过50条); } // 幂等性检查用客户端生成的batchId做去重 // 防止弱网环境下App重试提交同一批数据导致重复 String batchId list.get(0).getBatchId(); if (redisTemplate.hasKey(inspection: batchId)) { return ApiResponse.success(0); // 已处理过直接返回成功 } // 批量插入 int insertCount inspectionService.batchInsert(list); // 记录batchId到Redis有效期24小时 redisTemplate.opsForValue().set(inspection: batchId, 1, 24, TimeUnit.HOURS); return ApiResponse.success(insertCount); }这个接口的核心是幂等性处理。我踩过的坑是App 端在猪舍里信号差打了 30 分钟提交按钮没反应饲养员反复点后台收到好几遍相同的巡检数据猪只档案里的异常次数翻了三倍。加了这个 batchId 去重逻辑之后数据才真正可靠。4.2 实时数据推送WebSocket 心跳保活机制App 首页要展示猪舍的实时环境数据不能一直轮询 HTTP 接口否则流量和耗电都扛不住。我采用 WebSocket 建立长连接服务端每 5 秒推送一次最新环境数据。但手机熄屏后 WebSocket 会被系统断开恢复前台时要检测连接状态并自动重连// uni-app 或 Android WebView 前端代码中心跳重连逻辑 function initWebSocket() { const wsUrl wss://api.pigfarm.com/ws/realTime?token getToken(); ws new WebSocket(wsUrl); // 心跳包每30秒发一次ping服务端回pong heartbeatTimer setInterval(() { if (ws.readyState WebSocket.OPEN) { ws.send(JSON.stringify({ type: ping, ts: Date.now() })); } }, 30000); // 监听断开事件指数退避重连 ws.onclose () { clearInterval(heartbeatTimer); // 首次重连延迟2秒之后翻倍最大60秒 let retryDelay retryCount 5 ? Math.pow(2, retryCount) * 2000 : 60000; setTimeout(initWebSocket, retryDelay); retryCount; }; }4.3 文件上传耳标照片与健康检查图片的压缩方案饲养员巡检时给异常猪只拍照一张照片原图可能有 3-5MB猪场网络环境又不稳定直接传原图容易超时。我做了两层处理App 端先用 canvas 压缩到最大 800px 宽、质量 0.7 的 JPEG后端接收后校验文件类型和体积统一存储到对象存储服务内网自建 MinIO然后返回 URL。图片压缩后的平均大小在 100KB 左右弱网环境下上传成功率从 60% 提升到了 98%。5. 部署与运维让系统在猪场环境稳定跑起来5.1 服务器规划单机部署与双机热备一个存栏万头的猪场我推荐用两台物理服务器做双机热备而非上云。原因现实猪场通常在偏远地区公网带宽不稳定数据要留在本地。配置上一台主力服务器16核 32GB 内存2TB SSD跑 Java 后端 MySQL EMQX 消息服务另一台备用服务器配置相同跑 TDengine 和文件存储同时做主服务器的冷备。每天凌晨 2 点做增量备份每周日做全量备份。这个配置的吞吐量支撑两个万头猪场完全足够成本控制在几万元内比云服务器年费省下不少。5.2 数据备份策略秒级数据不能丢环境数据是连续采集的如果服务器宕机一小时这期间的数据就断了猪场环境变化曲线会出现缺口。我在 4G DTU 上启用了本地缓存功能——设备自带存储网络断开时数据缓存到本地网络恢复后自动补传。Java 后端的数据写入采用批量入库每 10 秒攒一批写入 TDengine减少 I/O 压力。备份上TDengine 支持按时间段导出数据文件我写了个定时任务每天把前一天的数据打包传到备用服务器保留 90 天。5.3 设备离线告警不能全指望 App 推送设备离线是物联网项目最常见的故障但排查链路长。我在后台管理页面专门做了一个「设备在线状态矩阵」横轴是时间纵轴是设备列表离线时段用红块标出一眼就能看出哪个时段、哪栋舍的设备集体掉线。常见原因排序4G 信号盲区猪舍的钢筋混凝土对信号衰减很强、SIM 卡欠费、DTU 电源被误关。我在每栋猪舍安排了一台信号增强器把 4G 天线引到窗外彻底解决了信号问题。6. 智慧化养猪 App 落地避坑五条真实场景排查记录6.1 数据延迟TDengine 查询突然变慢现象系统上线一个月后App 的历史曲线页打开要等 8 秒以上。原因TDengine 的保留策略没配好原始数据无限增长查询扫描的数据块太多。我们当时的保留策略只设了「数据永不删除」结果一个月就有近 2 亿条记录。解决重建数据库并设置合理的保留策略——原始数据保留 30 天超过 30 天的数据降采样为分钟级聚合数据保留 2 年。查询速度恢复到 500ms 以内。6.2 Modbus 数据错乱同一个传感器返回不同温度现象某传感器上午显示正常下午突然跳到 -40℃。原因Modbus 串行链路有两个设备地址冲突主站轮询时读到了错误设备的寄存器。现场排查发现是新增的一台采集器默认地址是 1和原有的 1 号设备冲突了。解决所有设备接入前必须检查地址分配表用 Modbus 调试工具逐台设备读取地址并重新分配确保全局唯一。6.3 告警风暴氨气传感器半小时推了 200 条告警现象某天上午App 的告警推送几乎每隔 10 秒响一次场长直接把通知权限关了。原因那一栋舍的风机故障停机氨气浓度快速上升我们的预警规则是「浓度超过 30ppm 即告警」每次上报都触发。解决在预警规则里加了「持续时间」条件——告警触发后如果 5 分钟内没有恢复才进行下一次推送同一条告警 30 分钟内最多重复推送 3 次。告警风暴立刻消除。6.4 APP 无法登录JWT 过期时间设置不合理现象饲养员早上登录 App中午再看就掉线需要重新输密码。原因我把 JWT 的有效期设成了 4 小时但饲养员一个班次是 8 小时中间必然掉线。而且没有做刷新令牌机制。解决改成双令牌方案——Access Token 有效期 8 小时Refresh Token 有效期 7 天。App 自动用 Refresh Token 去换取新的 Access Token用户感知不到掉线。6.5 控制指令失效远程开风机没反应现象场长在办公室远程打开 3 号风机App 显示「已发送」但风机没转。原因控制指令走 MQTT 主题设备端订阅了但指令的 topic 和设备实际监听的 topic 不一致。排查发现是配置文件中多了一个前缀/prod/。解决统一了 topic 命名规范并且加了「指令回执」逻辑——设备执行成功后上报一条确认消息后端 10 秒没收到回执就标记为失败并重试。7. 进阶玩法把 AI 视觉引入猪只健康监测App 做完了环境监测和档案管理更进一步的价值是猪只健康状态的自动识别。我用 Java 调用了开源的图像识别模型TensorFlow Serving对舍内摄像头抓拍的猪只图片做行为分析猪只的咳嗽声通过拾音器采集音频特征、站立/卧倒姿态异常、腹部呼吸频率加快都是呼吸道疾病的早期信号。这是非常前沿的尝试但要注意两点一是猪舍的摄像头安装位置要能覆盖整个栏位光照差时效果打折二是模型训练需要积累大量标注数据起步阶段可以先只检测「猪只长时间卧倒不起」这种强特征。我把这部分设计成独立的微服务通过 HTTP 与主应用通信不影响核心业务稳定性。实际跑下来对呼吸道疾病预警的准确率大约在 70% 左右还不能做到完全替代人工巡检但已经能显著降低漏检率。后续可以持续用新数据做增量训练同时结合环境数据氨气、温差做交叉验证让误报率进一步下降。这套方案给养殖场带来的收益是可量化的早发现一头病猪省下的治疗费和避免的死亡率足以覆盖整套系统的建设成本。做个不恰当的类比智慧化养猪 App 就像给猪场装了一套健康的神经系统环境是皮肤感受器预警是疼痛信号而 Java 后端就是那个不眠不休的脑干。希望帮到你。本文还有配套的精品资源点击获取