简介:农牧慧智能化养殖管理系统是一套面向农牧场数字化升级的工程源码,整合物联网设备数据采集、养殖环境实时监测、员工信息管理及动物健康预警等核心功能,适合农牧企业技术人员、开发者用于课程设计、毕业设计或真实项目二次开发。包体共70个文件,以58个Java源文件为绝对主体,辅以6个XML配置、YAML环境配置以及说明文档等,整体仅85KB,属于轻量级纯净代码工程,便于快速阅读与导入开发环境。已有46人学习/下载。系统采用Maven标准目录结构,主程序、测试代码与资源文件分层清晰,配合txt说明文档和docx附赠资源,可帮助读者理解物联网感知层如何接入业务逻辑,掌握员工排班、环境温湿度监测、健康预警与历史趋势分析等模块的编码思路,为后续扩展大数据预测、市场决策和竞争力提升功能提供扎实基础。
1. 智能化养殖管理系统,难点不在硬件而在数据闭环
有一次我去一个规模猪场看环控系统,大屏上温度、湿度、氨气曲线全部跳动,生产主管却抱怨“天天响警报,一条都不敢信”。问题不在传感器,而在于系统只停留在“采集和展示”:员工操作没有留痕,物联网数据没有跟动物健康关联,历史数据也没变成预测和决策依据。像“农牧慧智能化养殖管理系统”这类工程的真正价值,是把物联网感知、人员操作和生产结果串成一条闭环:环境实时监测负责发现问题,动物健康状况精准把控负责定位问题,员工信息便捷管理负责追踪责任,数据分析和预测功能负责提前预判,历史数据和趋势科学决策负责回答“下一步该怎么做”。这篇文章面向养殖企业信息化负责人、给养殖场做物联网方案的工程师,以及准备进入农业数据平台的研发人员。
2. 环境实时监测与动物健康的硬件链路怎么搭
2.1 环境监测参数怎么选、点位怎么布
最典型的大坑是传感器堆得多,但参数没用。对养殖环境来说,真正值得投入的是下面几个参数:温湿度决定采食量和热应激水平,氨气来自粪便发酵,浓度超过 20ppm 就会持续刺激动物呼吸道,CO2 反映通风效率,风速在夏季代表体感降温能力,光照影响产蛋节律和活动量。选型时可以参考这张常用参数表:
| 参数 | 常见量程 | 常见精度 | 采样周期 | 布点参考 |
|---|---|---|---|---|
| 温度 | 0~60℃ | ±0.3℃ | 15s~1min | 离地 1.2~1.5m,避开风机直吹 |
| 湿度 | 0~100%RH | ±3%RH | 15s~1min | 与温度同点位 |
| 氨气 | 0~100ppm | ±2ppm | 5min | 漏粪板上方 30cm |
| CO2 | 0~5000ppm | ±50ppm | 5min | 舍内中部、回风侧 |
| 风速 | 0~10m/s | ±0.2m/s | 1min | 进风口与风机侧各一点 |
采样周期不是越短越好。氨气电化学传感器寿命有限,5 分钟一次足够;温度变化快,15 秒一次即可。按一栋 5000 头育肥舍部署 10 个传感器、每 15 秒上送一次计算,一天会产生 57.6 万条记录,一年的原始数据量在 2.1 亿条左右。这个量级会影响后面的存储选型,所以先在这里摆出来。点位布控建议按栋舍面积估算,通常每 500 平方米设 3~5 个温湿度点,氨气测点放在粪污区附近,不要所有探头都集中在走道这一侧。
2.2 物联网链路选型与数据上送:为什么是MQTT
链路选择主要看部署环境和成本。舍内短距离用 RS485 总线或 LoRa 都可以,两者抗干扰能力强,LoRa 的额外好处是免布线,一个网关能覆盖几百米范围;出舍汇总后走 4G 或有线以太网到服务器。WiFi 在这个场景里是最差选项,养殖舍内金属结构和墙体多,2.4G 信号衰减快,断线率很容易上去。网关负责把不同协议统一成 MQTT 消息上送,MQTT 在弱网环境下表现好、消息头开销小,因此成为这类系统的默认选择。下面是一个环境采集节点常见的数据上报片段,MQTT QoS 用 1 而不是 2:
import json from datetime import datetime, timezone # 上报一条温湿度数据 payload = { "device_id": "HN-TH-03", # 栋舍-类型-序号 "ts": datetime.now(timezone.utc).isoformat(), # 统一使用UTC "values": {"temp": 28.5, "humidity": 72.3} } mqtt_client.publish("farm/barn01/env", json.dumps(payload), qos=1)device_id 建议编码成“栋舍-传感器类型-序号”,后端拿到这个 ID 就能直接定位空间位置,不需要再查映射表。时间戳统一转成 UTC 再存储,展示层按本地时区换算,否则遇到跨省部署或报表跨时段对比时很容易错位。QoS=1 只保证消息不丢、允许重复,环境数据重复上报由后端按时间戳去重即可;QoS=2 的确认握手更多,在弱网环境下反而容易积压。网关除了上送,还要在本地保留最近 24 小时的数据,断网时先写本地文件,恢复后按“原始发生时间”补传,不能按补传时刻打时间戳,否则历史曲线中间会出现一段不存在的断崖。
2.3 动物健康状况精准把控:组合规则比单点阈值可靠
动物健康监测更稳妥的做法,是无源 RFID 耳标配合读写器,这也是无源物联网在养殖业最成熟的落地点:动物不戴电池,读写器在料线或饮水区近距离识别个体,从而记录每头动物的采食次数和活动时长。如果只看体温这个单点指标,误报率会很高,猪的正常体温在 38.5℃ 左右,但运动、采食、应激都会让体温短时升高。更可靠的方式是把行为和环境信号绑在一起判断,采食频次、活动量、舍温、体重变化四个维度同时看。规则引擎建议写成可独立维护的配置而不是写死在代码里:
rules = [ { "name": "热应激预警", "conditions": { "temp_gte": 32, # 舍温超过32度 "activity_lte": "baseline*0.6", # 活动量低于基线60% "duration_min": 30 # 持续30分钟 }, "action": "alert_owner" }, { "name": "疑似消化道异常", "conditions": { "feed_times_lte": 3, # 当日采食少于3次 "last_feed_gap_min": 360 # 距上次采食超过6小时 }, "action": "inspect_pen" } ]这个规则文件的好处是,兽医或饲养员可以随时调整阈值,不需要重新发布程序。温度上限必须按阶段区分:育肥后期 32℃ 才预警,产房母猪 28℃ 就要触发。活动量基线用过去 7 天同一时段的平均值,而不是全天平均值,因为动物本身就有早晚活动高峰。任何健康预警都要以“持续时长”为前提,喂料前后的短暂兴奋不应该触发通知。规则命中后,同时记录告警事件和当时的传感器快照,方便事后回溯现场。
3. 员工信息便捷管理的关键是把“人”和“批次”绑牢
3.1 员工管理要回答的不只是考勤
不少养殖管理系统的员工模块只做两件事:花名册和打卡。但生产上真正关心的是操作留痕和责任可追溯:这批料是谁喂的?这次免疫是谁执行的?转栏操作有没有按时完成?“员工信息便捷管理”体现在,这些答案在手机上几次点选就能确认下来,系统里维护的不只是“在场人员”,而是“谁在哪个时间点对哪一批动物做了什么操作”。
常见做法是给员工划分责任区,把栋舍和批次的权限绑定到账号。饲养员到达责任栋舍后,扫码或打卡才能执行任务;任务来源于生产计划,系统按批次日龄自动生成当日的喂料、免疫、转栏计划,员工在移动端确认执行结果。这样员工管理和生产数据就自然关联到了一起,而不是两套互不相通的系统。
3.2 四张核心表与操作记录落库
先分清四张基础表:employee(员工档案)、house(栋舍)、batch(批次)、operation_record(操作记录)。员工表里用 role 字段区分场长、兽医、饲养员、设备管理员;批次表记录品种、进场日期、预期出栏日期;操作记录是整个系统的关键流水。
| 表名 | 核心职责 | 关键字段 |
|---|---|---|
| employee | 员工身份与权限 | id, name, role, house_id |
| house | 栋舍档案 | id, name, area, sensor_group_id |
| batch | 批次档案 | id, breed, start_date, expected_end_date |
| operation_record | 操作流水留痕 | batch_id, employee_id, op_type, occurred_at |
operation_record 建表可以参照下面这个简化版本:
CREATE TABLE operation_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, batch_id INT NOT NULL COMMENT '养殖批次ID', house_id INT NOT NULL COMMENT '栋舍ID', employee_id INT NOT NULL COMMENT '操作人', op_type VARCHAR(32) NOT NULL COMMENT 'feeding/vaccine/transfer', planned_amount DECIMAL(10,2) COMMENT '计划值,如计划喂料量', actual_amount DECIMAL(10,2) COMMENT '实际执行值', device_log_id BIGINT COMMENT '关联物联设备日志ID', occurred_at DATETIME NOT NULL COMMENT '操作发生时间', INDEX idx_batch_time(batch_id, occurred_at), INDEX idx_employee(employee_id, occurred_at) ) COMMENT='养殖操作流水';同时记录计划值和实际值,是为了计算“执行偏差率”,这个指标可考核,也作为后续采食量预测模型的输入。device_log_id 字段把人工操作和设备日志关联起来,比如一次饲喂记录对应一次料线启动日志,后续分析“人工加料是否导致料槽剩余异常”时不用靠回忆。年出栏十万头以上的规模,操作流水建议按月份做分区表,避免查询某个批次历史时全表扫描。账号体系不在这里展开,重点是操作数据如何进入分析链路。
3.3 一条查询:员工操作偏差与批次健康联动
数据落库后,员工管理的价值体现在查询上。下面这条 SQL 汇总最近 30 天每个员工的操作量和平均偏差率,常被用于月度绩效评估:
SELECT e.employee_name, b.batch_no, COUNT(r.id) AS op_count, AVG(ABS(r.actual_amount - r.planned_amount) / NULLIF(r.planned_amount, 0)) AS avg_deviation FROM operation_record r JOIN employee e ON r.employee_id = e.id JOIN batch b ON r.batch_id = b.id WHERE r.occurred_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) GROUP BY e.id, b.batch_no HAVING avg_deviation > 0.05 ORDER BY avg_deviation DESC;HAVING avg_deviation > 0.05 是偏差率红线,表示喂料量偏差超过 5% 的员工自动进入预警清单。NULLIF 的用途是防止计划量为零时除数为零而报错。把这张表的结果再和物联网监测数据关联起来,可以回答“某栋舍连续三天氨气超标,与夜班值班人员的操作记录是否存在直接关系”这类问题。这套逻辑可以放进日报里每天自动推送给场长,而不是月末再拉 Excel 复盘。
4. 数据分析和预测功能:从历史库到决策建议
4.1 数据分层存储:时序库和关系库各管一摊
物联网环境数据与业务操作数据的访问模式不同,最好分开存储。环境数据以时间为维度连续追加,适合放进 TDengine 或 InfluxDB 这类时序数据库,按时间和设备标签查询时,即使到十亿行级别过滤也很快;员工信息、批次、操作记录这类事务型数据继续放在 MySQL 或 PostgreSQL 里。混合部署时,规则引擎读取时序库,报表系统读取关系库,两边通过 batch_id 和 house_id 关联。参考保留策略如下:
| 数据类别 | 存储引擎 | 保留周期 | 说明 |
|---|---|---|---|
| 5分钟环境原始数据 | TDengine/InfluxDB | 90天 | 故障追溯、模型回测 |
| 天级聚合数据 | TDengine/InfluxDB | 2年 | 季节趋势分析 |
| 员工操作流水 | MySQL/PG | 永久 | 绩效和合规审计 |
| 批次档案和结算 | MySQL/PG | 永久 | 财务和决策基座 |
不要把原始传感器数据永久保留。存储成本放在一边,物联网设备更新换代后,老数据的单位、采集频率很难兼容新模型;保留 90 天足以覆盖一次完整育肥周期。需要长期分析的数据,通过定时任务聚合到天级,聚合结果保留 min、max、avg 三列,分别用于异常检测和趋势分析,如果只留日均值,昼夜波动这些关键信息就被抹平了。
4.2 清洗与缺失插补:别让坏数据进预测模型
报表可以容忍脏数据,预测模型不行。传感器探头受潮、网关抖动一次,都可能生成一个离群点,让模型学到错误的趋势。环境数据清洗我一般用滚动窗口 z-score:
import pandas as pd def clean_sensor(s: pd.Series) -> pd.Series: # 1小时滑动窗口均值和标准差,避免昼夜波动造成全局误判 mean = s.rolling("1h").mean() std = s.rolling("1h").std() z = (s - mean) / std s[z.abs() > 3] = pd.NA # 与滚动均值偏差超过3倍标准差 return s.fillna(method="ffill").fillna(method="bfill")这里用滚动窗口而不是全局均值,是因为舍内温度存在明显的昼夜周期,白天和凌晨的温差可能超过 8℃,按全天均值和标准差计算,清晨正常观测值反而会被标记成异常。缺失值用 ffill 回填之前,要先判断缺失段长度:断档超过 2 小时属于设备故障,应该进入告警而不要静默插补。另一个常见错误是直接把离群点替换成均值,更合理的做法是原位置保留缺失标记,交给下游统一处理。
4.3 环境趋势预测:用 Prophet 预测未来24小时温湿度
环控目前最大的痛点是响应滞后,温度已经超限了风机才动作。预测的价值在于提前调度,比如根据未来一小时的温度趋势提前开启湿帘。养殖舍温湿度有清晰的昼夜周期和季节周期,Prophet 把趋势、季节项、节假日常数项分开建模,对周期信号拟合效果好,也能容忍缺失值。下面是最小可运行的预测代码:
from prophet import Prophet import pandas as pd # 历史数据列: timestamp(UTC), temp df = pd.read_csv("barn1_temp.csv", parse_dates=["timestamp"]) data = df.rename(columns={"timestamp": "ds", "temp": "y"})[["ds", "y"]] model = Prophet(daily_seasonality=True, weekly_seasonality=True) model.fit(data) future = model.make_future_dataframe(periods=96, freq="15min") # 未来24小时 forecast = model.predict(future)daily_seasonality=True 让模型学习昼夜温度曲线,weekly_seasonality 能捕捉周末人员作息变化对通风的影响。periods=96 对应 15 分钟粒度、未来 24 小时的数据量。预测结果最好的用途不是显示到页面上,而是作为环控联动的前馈信号:预测未来 30 分钟温度上升超过 1.5℃,提前一档开启风机。类似做法在气象预测、光伏功率预测场景里是同一套思路。这类模型需要定期增量拟合,建议每天凌晨跑一次,否则季节转换时预测结果会滞后接近半个月。
4.4 体重与出栏预测:随机森林和它的三个特征
出栏体重预测是养殖场最愿意买单的功能。它不需要高频数据,以周为粒度采集采食量、日龄和环境累积特征就够。下面是一个随机森林最小实现:
from sklearn.ensemble import RandomForestRegressor features = ["age_day", # 日龄 "avg_daily_feed", # 近7天日均采食量(kg) "days_gt_28"] # 累计高温天数(>28度) X, y = df[features], df["weight_kg"] model = RandomForestRegressor( n_estimators=300, max_depth=8, # 限制深度,防过拟合 min_samples_leaf=5) # 叶节点最少样本数,增强泛化 model.fit(X, y)max_depth=8 和 min_samples_leaf=5 是相对保守的经验参数。养殖数据量通常只有几万条,树太深容易把噪声记进去。days_gt_28 这个特征比直接用平均气温更有效,因为热应激是累积效应,连续三天高温和单日高温的处理策略完全不同。模型训练后要按批次回测,不能全局打乱训练集否则同一个批次的样本同时出现在训练集和测试集,评估结果会虚高。喂料数据来自第 3 章的 operation_record,环境累积特征来自第 2 章的时序库,两个数据源在这里汇合,也就是前面章节建立联动的本质。每次模型输出的 MAE 要持续记录,一旦周度 MAE 超过 2kg,优先检查传感器校准和员工操作记录质量。
4.5 历史数据和趋势科学决策:几个必看的指标
生产决策不能只看“今天死淘了几头”。有了历史数据支撑,至少要把下面四个指标做成周粒度趋势线:
| 指标 | 计算公式 | 预警方向 |
|---|---|---|
| 料肉比 FCR | 总采食量 / 总增重 | 连续两周上升 |
| 日增重 ADG | (末重-初始重) / 饲养天数 | 低于品种标准 |
| 出栏整齐度 | 出栏体重变异系数 CV | CV 大于 10% |
| 死淘率 | 期内死亡数 / 平均存栏 | 超过阶段阈值 |
以 FCR 为例,只看单周数值没有意义,要和近 12 周趋势做对比。如果全场整体上升,优先检查料线损耗和饲料配方;如果只有某一栋突然上升,就需要把员工操作记录和该栋环控数据拉出来对照。这四张趋势图配合 4.3 节的预测输出,就能让“历史数据和趋势科学决策”落到每周例会的固定议题上,而不是等出栏结算完再复盘。
5. 上线前后让“历史数据和趋势”真正帮到决策的技巧
5.1 新旧系统并行,先证明数据可信
系统上线最大的阻力来自“数据不准”四个字。我一般的做法是并行采集:新系统上线后,传感器和原有的人工抄表同步记录 2~4 周,再对比两者同一时间点的读数。以舍内温度为例,人工抄表和传感器读数的平均误差应该控制在 ±0.5℃ 以内,否则要检查探头和温度计是否不在同一个点位,或者传感器是不是装在风机直吹的位置。这一步不做,后面的预测和报警都缺少公信力。
5.2 报警降噪:从“天天喊狼”到分级推送
前文提到的那家猪场每天几百条报警,根因是报警逻辑只做单点阈值判断。降噪的标准做法是加“持续时长”和“恢复条件”:温度超过 32℃ 不马上报警,连续 15 分钟仍超限才触发;如果未来 10 分钟回落趋势明显,推送等级降为提醒。报警还要分级:
| 级别 | 示例 | 处理时限 |
|---|---|---|
| 紧急 | 氨气持续 40ppm,动物表现异常 | 立即处置 |
| 严重 | 温度持续超标且无回落趋势 | 30 分钟内响应 |
| 提醒 | 单点传感器数据缺口超过 2 小时 | 当班确认 |
分级之后,场长每天需要处理的告警尽量控制在一屏以内,系统才算真正进入可用状态。
5.3 模型回测与一栋舍起步的最小闭环
预测模型在正式上线前,拿最近 30 天数据做回放验证是必须的。用前 23 天训练,对后 7 天逐日预测,再计算 MAE:
from sklearn.metrics import mean_absolute_error train = df.iloc[:-7] # 前23天训练 test = df.iloc[-7:] # 后7天回测 model = RandomForestRegressor(n_estimators=300, max_depth=8, min_samples_leaf=5) model.fit(train[features], train["weight_kg"]) mae = mean_absolute_error(test["weight_kg"], model.predict(test[features])) print("回测MAE:", mae)回测只按时间顺序切分,不能像普通机器学习那样随机打乱。落地时建议不要全线铺开,先挑一栋示范舍,跑通“环境数据采集 → RFID 个体识别 → 员工扫码执行任务 → 日报自动推送”的闭环,确认数据质量连续三天稳定后,再接入第一个预测模型,通常从舍温预测开始。一个批次的数据闭环后逐步扩展。整个系统的验收标准,最终要落到月度经营会上可以直接查看的 FCR 趋势线和报警响应率,而不是大屏上的数字跳动得是否好看。
本文还有配套的精品资源,点击获取