

档案库房微环境调控的核心,不是把恒湿设备"打开"就完事,而是让分布在库房各处的温湿度传感器实时采集的数据,成为恒湿设备启停、调速、切换模式的决策依据,形成"感知→判断→执行→反馈"的完整闭环。
某省级档案馆特藏库(面积 800㎡,存放古籍、舆图、胶片)曾遇到典型问题:库房内安装了 6 台恒湿一体机,每台独立设定 50%RH 目标值,各自内置传感器做本地控制。结果库房门口区域湿度 42%RH(偏低),库房深处 58%RH(偏高),各台设备互相"打架"——门口的机器拼命加湿,湿气被空调气流推到深处,深处的机器又启动除湿,形成无效循环,月耗电量 1.8 万度,湿度均匀性 ±8%RH。
改造后采用"分布式感知 + 集中决策 + 分区执行"架构,湿度均匀性提升到 ±2%RH,能耗下降 41%。以下是完整实施路径。
┌─────────────────────────────────────────────────────────────────────────┐
│ 微环境调控闭环架构 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 感知层(分布式传感器网络) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 门口区 │ │ 中部区 │ │ 深处区 │ │ 密集架 │ ... │
│ │ 4台 │ │ 8台 │ │ 4台 │ │ 内部4台 │ │
│ │ TH-001 │ │ TH-009 │ │ TH-017 │ │ TH-021 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬─────┴───────────┘ │
│ │ Modbus TCP / MQTT │
│ ▼ │
│ 边缘决策层(区域控制器 / 工控机) │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 控制引擎 │ │
│ │ ├── 数据采集:轮询 20 台传感器,5s 周期 │ │
│ │ ├── 空间聚合:按分区计算均值、极值、梯度 │ │
│ │ ├── 控制算法:PID + 模糊规则 + 防振荡逻辑 │ │
│ │ ├── 设备调度:决定哪台设备启/停/调速/模式切换 │ │
│ │ └── 安全联锁:高温保护、故障切换、手动优先 │ │
│ └───────────────────────────┬───────────────────────────────────────┘ │
│ │ Modbus RTU / TCP / 继电器 │
│ ▼ │
│ 执行层(恒湿设备) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 恒湿机1 │ │ 恒湿机2 │ │ 恒湿机3 │ │ 恒湿机4 │ ... │
│ │ AHU-01 │ │ AHU-02 │ │ AHU-03 │ │ AHU-04 │ │
│ │ 加湿+ │ │ 除湿+ │ │ 加湿+ │ │ 除湿+ │ │
│ │ 除湿 │ │ 除湿 │ │ 除湿 │ │ 除湿 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬─────┴───────────┘ │
│ │ 回风温湿度反馈 │
│ ▼ │
│ 反馈层(效果验证) │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 对比控制前后各分区传感器数值变化 │ │
│ │ → 湿度偏差收敛到目标区间? │ │
│ │ → 各分区均匀性改善? │ │
│ │ → 设备运行时间分配均衡? │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ 偏差信号回到决策层 │
│ (闭环迭代) │
└─────────────────────────────────────────────────────────────────────────┘库房不是均匀空间,不同位置的传感器对控制决策的贡献不同:
分区定义(800㎡ 特藏库示例):
┌──────────────────────────────────────────────────────────────┐
│ 库房平面(俯视) │
│ │
│ ┌──────────────────────────────────────────────────────────┐│
│ │ 缓冲区(走廊) │ 恒湿机1 │ 恒湿机2 ││
│ │ │ AHU-01 │ AHU-02 ││
│ ├────────────────────────────────┼──────────┼──────────┤│
│ │ 门口区(4台传感器) │ │ ││
│ │ 权重 1.2(门开闭影响大) │ │ ││
│ │ TH-001 ~ TH-004 │ │ ││
│ ├────────────────────────────────┼──────────┼──────────┤│
│ │ 中部区(8台传感器) │ │ ││
│ │ 权重 1.0(稳定参考区) │ │ ││
│ │ TH-005 ~ TH-012 │ │ ││
│ ├────────────────────────────────┼──────────┼──────────┤│
│ │ 深处区(4台传感器) │ 恒湿机3 │ 恒湿机4 ││
│ │ 权重 1.1(气流末端,易偏高) │ AHU-03 │ AHU-04 ││
│ │ TH-013 ~ TH-016 │ │ ││
│ ├────────────────────────────────┼──────────┼──────────┤│
│ │ 密集架内部(4台传感器) │ │ ││
│ │ 权重 1.5(档案直接环境,最关键)│ │ ││
│ │ TH-017 ~ TH-020 │ │ ││
│ └────────────────────────────────┴──────────┴──────────┘│
└──────────────────────────────────────────────────────────────┘
控制目标值:
温度:20 ± 2℃(GB/T 27703 纸质档案要求 14~24℃)
湿度:50 ± 5%RH(要求 45~60%RH,控制目标收紧到 50±5)
加权空间均值计算:
H_space = Σ(w_i × H_i) / Σ(w_i)
示例:
门口区均值 48%RH × 1.2 = 57.6
中部区均值 51%RH × 1.0 = 51.0
深处区均值 53%RH × 1.1 = 58.3
密集架均值 49%RH × 1.5 = 73.5
─────────────────────────────
加权均值 = (57.6+51.0+58.3+73.5) / (1.2+1.0+1.1+1.5)
= 240.4 / 4.8 = 50.08%RH ✅ 达标温度 PID(慢过程,大惯性):
Kp = 0.8 (比例增益,不宜过大,避免空调频繁启停)
Ki = 0.05 (积分时间 1200s,消除稳态误差)
Kd = 2.0 (微分时间 60s,抑制温度快速波动)
采样周期:30s
输出限幅:0~100%(对应冷水阀开度 / 加热功率)
湿度 PID(比温度更慢,且存在滞后):
Kp = 1.2 (湿度响应比温度快,增益可略大)
Ki = 0.08 (积分时间 750s)
Kd = 3.0 (微分时间 45s,提前抑制湿度超调)
采样周期:15s
输出限幅:0~100%(对应加湿阀开度 / 除湿压缩机频率)
抗积分饱和策略:
├── 当湿度进入 ±2%RH 死区时,积分项冻结
├── 当设备处于最大出力仍无法达到目标时,积分项限幅
└── 模式切换(加湿→除湿)时,积分项清零PID 适合稳态调节,但库房环境存在非线性干扰(开门、人员进出、设备启停),需要模糊规则补充:
模糊规则表(湿度控制):
输入变量:
E = 当前湿度 - 目标湿度(%RH)
EC = 湿度变化率(%RH/min)
输出变量:
U = 控制量(加湿/除湿强度,0~100%)
规则示例:
IF E is 负大(NB) AND EC is 负(N) → U = 强加湿(90%)
IF E is 负大(NB) AND EC is 零(Z) → U = 中加湿(70%)
IF E is 负中(NM) AND EC is 正(P) → U = 弱加湿(30%)
IF E is 零(Z) AND EC is 零(Z) → U = 维持(0%)
IF E is 正小(PM) AND EC is 负(N) → U = 弱除湿(30%)
IF E is 正大(PB) AND EC is 正(P) → U = 强除湿(90%)
IF |E| < 1%RH → U = 0%(死区)
防振荡规则(关键):
IF 湿度变化率 > 2%RH/min → 限制输出变化率 ≤ 10%/min
IF 同一设备连续启停 < 5min → 锁定该设备 10min 内不允许重启
IF 相邻两台设备输出方向相反 → 降低响应速度,避免"打架"恒湿一体机通常提供 Modbus RTU(RS485)或 Modbus TCP 接口:
恒湿机 Modbus TCP 寄存器表(通用型):
| 寄存器地址 | 功能码 | 含义 | 类型 | 读写 | 说明 |
|---|---|---|---|---|---|
| 40001 | 03 | 运行模式 | UINT16 | R/W | 0=停机 1=自动 2=手动加湿 3=手动除湿 4=通风 |
| 40002 | 03 | 目标湿度设定 | UINT16 | R/W | 单位 %RH,范围 30~80 |
| 40003 | 03 | 湿度死区 | UINT16 | R/W | 单位 %RH,默认 2 |
| 40004 | 03 | 加湿阀开度 | UINT16 | R/W | 0~100% |
| 40005 | 03 | 除湿压缩机频率 | UINT16 | R/W | 0~100%(变频型) |
| 40006 | 03 | 风机转速 | UINT16 | R/W | 0~100% |
| 40007 | 03 | 当前回风湿度 | UINT16 | R | 实际值×10 |
| 40008 | 03 | 当前回风温度 | INT16 | R | 实际值×10 |
| 40009 | 03 | 设备状态字 | UINT16 | R | bit0=运行 bit1=故障 bit2=加湿中 bit3=除湿中 |
| 40010 | 03 | 故障代码 | UINT16 | R | 0=无故障 1=高压 2=低压 3=缺相 ... |
| 40011 | 03 | 累计运行时间 | UINT32 | R | 小时(占 2 个寄存器) |
| 40013 | 03 | 滤网使用时长 | UINT16 | R | 小时 |
| 40014 | 06 | 远程/本地切换 | UINT16 | W | 0=本地 1=远程 |控制模式优先级(从高到低):
1. 紧急停机(最高)
└── 消防信号触发 / 手动急停按钮 → 所有设备立即停机
2. 手动模式
└── 运维人员在触摸屏上手动指定运行模式和参数
3. 时间表模式
└── 按预设时间表运行(如工作日 8:00-18:00 自动,其余时段节能)
4. 闭环自动模式(最低,正常状态)
└── 由传感器数据驱动 PID + 模糊控制
模式切换条件:
├── 本地/远程切换:设备端拨码开关 → 远程时组态软件才能下发控制
├── 自动→手动:运维人员操作 / 通信中断超过 3 分钟
├── 手动→自动:通信恢复 + 手动确认
└── 紧急→正常:故障排除 + 复位 + 手动确认#!/usr/bin/env python3
"""
档案库房恒湿设备闭环控制引擎
运行于边缘工控机,周期性采集传感器数据 → 计算控制量 → 下发设备
"""
import asyncio
import struct
from datetime import datetime, timedelta
from collections import deque
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
handlers=[logging.FileHandler('/var/log/env_control/engine.log'),
logging.StreamHandler()]
)
logger = logging.getLogger(__name__)
# ========== PID 控制器 ==========
class PIDController:
def __init__(self, Kp, Ki, Kd, setpoint, sample_time, output_limits=(0, 100)):
self.Kp = Kp
self.Ki = Ki
self.Kd = Kd
self.setpoint = setpoint
self.sample_time = sample_time
self.output_limits = output_limits
self._integral = 0.0
self._prev_error = 0.0
self._last_time = None
self._last_output = 0.0
self._integral_frozen = False
def compute(self, process_value, current_time):
"""计算 PID 输出"""
if self._last_time is None:
self._last_time = current_time
self._prev_error = self.setpoint - process_value
return 0.0
dt = (current_time - self._last_time).total_seconds()
if dt < self.sample_time:
return self._last_output
error = self.setpoint - process_value
P = self.Kp * error
# 积分项(带抗饱和和冻结逻辑)
if not self._integral_frozen:
self._integral += error * dt
# 积分限幅
i_max = 500.0 / self.Ki if self.Ki > 0 else 500.0
self._integral = max(-i_max, min(i_max, self._integral))
I = self.Ki * self._integral
# 微分项(对测量值微分,避免设定值跳变引起冲击)
derivative = -(process_value - (self.setpoint - self._prev_error)) / dt
D = self.Kd * derivative
output = P + I + D
output = max(self.output_limits[0], min(self.output_limits[1], output))
self._prev_error = error
self._last_time = current_time
self._last_output = output
return output
def freeze_integral(self):
"""进入死区时冻结积分"""
self._integral_frozen = True
def unfreeze_integral(self):
self._integral_frozen = False
def reset(self):
"""模式切换时清零"""
self._integral = 0.0
self._prev_error = 0.0
self._last_output = 0.0
# ========== 传感器数据聚合 ==========
class SensorAggregator:
def __init__(self):
self.sensors = {} # sensor_id -> {humidity, temperature, timestamp, weight}
self.history = deque(maxlen=100) # 历史均值序列
def update(self, sensor_id, humidity, temperature, weight=1.0):
self.sensors[sensor_id] = {
'humidity': humidity,
'temperature': temperature,
'timestamp': datetime.now(),
'weight': weight
}
def get_weighted_humidity(self):
"""计算加权空间湿度均值"""
if not self.sensors:
return None, 0
total_weighted = 0.0
total_weight = 0.0
valid_count = 0
for s in self.sensors.values():
# 丢弃超过 60s 未更新的数据
if (datetime.now() - s['timestamp']).total_seconds() > 60:
continue
total_weighted += s['humidity'] * s['weight']
total_weight += s['weight']
valid_count += 1
if total_weight == 0:
return None, valid_count
return total_weighted / total_weight, valid_count
def get_gradient(self):
"""计算湿度梯度(相邻分区差值)"""
zones = {}
for sid, s in self.sensors.items():
zone = sid.split('-')[0] # TH-A01-01 → A01
if zone not in zones:
zones[zone] = []
zones[zone].append(s['humidity'])
zone_means = {z: sum(v)/len(v) for z, v in zones.items()}
if len(zone_means) < 2:
return 0.0
values = list(zone_means.values())
return max(values) - min(values) # 最大梯度
# ========== 恒湿设备控制器 ==========
class HumidityController:
def __init__(self, modbus_client, device_addr, pid_params):
self.client = modbus_client
self.addr = device_addr
self.pid = PIDController(**pid_params)
self.mode = 'AUTO' # AUTO / MANUAL / EMERGENCY
self.last_output_time = None
self.running_state = 0 # 0=停机 1=加湿 2=除湿
self.output_rate_limit = 10.0 # %/min,变化率限制
async def set_remote_mode(self):
"""切换到远程控制模式"""
try:
await self.client.write_register(40014 - 40001, 1, slave=self.addr)
logger.info(f"设备 {self.addr} 已切换到远程模式")
except Exception as e:
logger.error(f"切换远程模式失败: {e}")
async def read_status(self):
"""读取设备状态"""
try:
rr = await self.client.read_holding_registers(40009 - 40001, 2, slave=self.addr)
status_word = rr.registers[0]
fault_code = rr.registers[1]
return {
'running': bool(status_word & 0x01),
'fault': bool(status_word & 0x02),
'humidifying': bool(status_word & 0x04),
'dehumidifying': bool(status_word & 0x08),
'fault_code': fault_code
}
except Exception as e:
logger.error(f"读取设备 {self.addr} 状态失败: {e}")
return None
async def control(self, target_humidity, current_humidity, timestamp):
"""执行一次控制循环"""
if self.mode != 'AUTO':
return
# 读取设备状态
status = await self.read_status()
if status and status['fault']:
logger.warning(f"设备 {self.addr} 故障,故障码: {status['fault_code']}")
return
# PID 计算
self.pid.setpoint = target_humidity
output = self.pid.compute(current_humidity, timestamp)
# 死区判断(±2%RH)
error = target_humidity - current_humidity
if abs(error) < 2.0:
self.pid.freeze_integral()
# 进入死区,维持当前状态或缓慢停机
if abs(error) < 1.0:
await self._stop()
return
else:
self.pid.unfreeze_integral()
# 确定运行模式
if error > 0: # 需要加湿
mode = 2 # 手动加湿
power = min(output, 100)
await self._set_humidify(mode, power)
else: # 需要除湿
mode = 3 # 手动除湿
power = min(abs(output), 100)
await self._set_dehumidify(mode, power)
async def _set_humidify(self, mode, power):
"""设置加湿"""
try:
# 写入运行模式
await self.client.write_register(40001 - 40001, mode, slave=self.addr)
# 写入加湿阀开度
await self.client.write_register(40004 - 40001, int(power), slave=self.addr)
# 写入目标湿度
await self.client.write_register(40002 - 40001, int(self.pid.setpoint), slave=self.addr)
logger.debug(f"设备 {self.addr} 加湿,开度 {power:.1f}%")
except Exception as e:
logger.error(f"设备 {self.addr} 加湿控制失败: {e}")
async def _set_dehumidify(self, mode, power):
"""设置除湿"""
try:
await self.client.write_register(40001 - 40001, mode, slave=self.addr)
# 写入除湿压缩机频率
await self.client.write_register(40005 - 40001, int(power), slave=self.addr)
await self.client.write_register(40002 - 40001, int(self.pid.setpoint), slave=self.addr)
logger.debug(f"设备 {self.addr} 除湿,频率 {power:.1f}%")
except Exception as e:
logger.error(f"设备 {self.addr} 除湿控制失败: {e}")
async def _stop(self):
"""停机"""
try:
await self.client.write_register(40001 - 40001, 0, slave=self.addr)
logger.debug(f"设备 {self.addr} 停机")
except Exception as e:
logger.error(f"设备 {self.addr} 停机失败: {e}")
# ========== 主控制循环 ==========
class ControlEngine:
def __init__(self):
self.aggregator = SensorAggregator()
self.controllers = {} # device_id -> HumidityController
self.target_humidity = 50.0 # %RH
self.target_temperature = 20.0 # ℃
self.running = False
def register_controller(self, device_id, controller):
self.controllers[device_id] = controller
async def run(self):
"""主循环"""
self.running = True
logger.info("控制引擎启动")
while self.running:
try:
now = datetime.now()
# 1. 采集传感器数据(实际项目中通过 MQTT/Modbus 获取)
# self._collect_sensor_data()
# 2. 计算空间加权均值
weighted_h, valid_count = self.aggregator.get_weighted_humidity()
if weighted_h is None:
logger.warning("无有效传感器数据,跳过本轮控制")
await asyncio.sleep(5)
continue
# 3. 计算湿度梯度
gradient = self.aggregator.get_gradient()
if gradient > 8.0:
logger.warning(f"湿度梯度过大: {gradient:.1f}%RH,可能存在气流死角")
# 4. 模糊规则补充判断
rate = self._calc_humidity_rate() # 变化率 %RH/min
if rate > 2.0:
logger.info(f"湿度变化过快 {rate:.2f}%RH/min,限制输出变化率")
for c in self.controllers.values():
c.output_rate_limit = 5.0 # 收紧到 5%/min
else:
for c in self.controllers.values():
c.output_rate_limit = 10.0
# 5. 下发控制到各设备
for device_id, controller in self.controllers.items():
await controller.control(
self.target_humidity,
weighted_h,
now
)
# 6. 记录控制日志
logger.info(
f"控制周期完成 | "
f"空间湿度均值: {weighted_h:.1f}%RH | "
f"有效测点: {valid_count} | "
f"梯度: {gradient:.1f}%RH | "
f"变化率: {rate:.2f}%RH/min"
)
# 7. 等待下一个周期
await asyncio.sleep(15) # 15s 控制周期
except Exception as e:
logger.error(f"控制循环异常: {e}", exc_info=True)
await asyncio.sleep(5)
def _calc_humidity_rate(self):
"""计算湿度变化率"""
if len(self.aggregator.history) < 2:
return 0.0
recent = list(self.aggregator.history)[-1]
prev = list(self.aggregator.history)[-2]
dt = (recent['time'] - prev['time']).total_seconds() / 60.0 # 分钟
if dt <= 0:
return 0.0
return (recent['humidity'] - prev['humidity']) / dt
def stop(self):
self.running = False
logger.info("控制引擎停止")
# ========== 主程序 ==========
async def main():
engine = ControlEngine()
# 初始化控制器(实际项目中从配置文件加载)
# modbus_client = await init_modbus_client()
# for dev_id, params in device_configs.items():
# ctrl = HumidityController(modbus_client, params['addr'], pid_params)
# await ctrl.set_remote_mode()
# engine.register_controller(dev_id, ctrl)
# 启动控制引擎
# await engine.run()
logger.info("控制引擎初始化完成(示例模式,未连接实际设备)")
if __name__ == '__main__':
asyncio.run(main())多台恒湿机并存时,需要调度策略避免互相干扰:
调度策略:
1. 轮值运行(延长设备寿命)
├── 4 台恒湿机按时间片轮流作为"主设备"
├── 每 24 小时轮换一次
├── 主设备负责精细调节(PID 输出 30~80%)
└── 从设备只做粗调(PID 输出 0~30% 或待机)
2. 负载均衡
├── 跟踪每台设备累计运行时间
├── 优先启动累计运行时间最短的设备
└── 当某台设备运行时间超过平均值的 120% 时,强制轮换
3. 协同防振荡
├── 相邻设备禁止输出方向相反(一台加湿、一台除湿)
├── 当分区湿度梯度 > 5%RH 时,启动"定向调控":
│ → 湿度偏低的区域对应的设备优先加湿
│ → 湿度偏高的区域对应的设备优先除湿
└── 全局湿度达标后,所有设备进入低功耗待机(风机低速运转)
4. 故障切换
├── 设备通信中断 > 30s → 标记为故障
├── 故障设备上的负载自动转移到同区域其他设备
└── 如果同区域无可用设备 → 上报告警,启动备用机组┌─────────────────────────────────────────────────────────────────────────┐
│ 档案库房微环境调控 - 实时状态 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 空间湿度分布(实时) │ │
│ │ │ │
│ │ 目标: 50%RH 当前均值: 49.8%RH 梯度: 2.3%RH 状态: 正常 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 门口区 │ │ 中部区 │ │ 深处区 │ │ 密集架 │ │ │
│ │ │ 48.2%RH │ │ 50.1%RH │ │ 51.5%RH │ │ 49.6%RH │ │ │
│ │ │ ██████░░ │ │ ██████░░ │ │ ██████░░ │ │ ██████░░ │ │ │
│ │ │ 4/4 在线 │ │ 8/8 在线 │ │ 4/4 在线 │ │ 4/4 在线 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 恒湿设备状态 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ AHU-01 │ │ AHU-02 │ │ AHU-03 │ │ │
│ │ │ 运行中 │ │ 运行中 │ │ 待机 │ │ │
│ │ │ 模式: 自动 │ │ 模式: 自动 │ │ 模式: 自动 │ │ │
│ │ │ 加湿 45% │ │ 除湿 30% │ │ ── │ │ │
│ │ │ 回风 48.2% │ │ 回风 50.1% │ │ ── │ │ │
│ │ │ 运行 1240h │ │ 运行 1180h │ │ 运行 1305h │ │ │
│ │ │ [手动] [停止]│ │ [手动] [停止]│ │ [手动] [启动]│ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ 轮值状态: AHU-01 为主设备 (剩余 14h 轮换) │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ 趋势曲线 (最近 2 小时) │ │
│ │ │ │
│ │ 55% ──────────────────────────────────────────── │ │
│ │ ╭───╮ ╭───╮ ╭───╮ │ │
│ │ 50% ─╯ ╰─────╯ ╰─────╯ ╰─────── 目标线 │ │
│ │ ╰───╯ ╰───╯ ╰───╯ │ │
│ │ 45% ──────────────────────────────────────────── │ │
│ │ | | | | | | │ │
│ │ 10:00 10:30 11:00 11:30 12:00 12:30 │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ [手动模式] [参数设置] [趋势查询] [报警记录] [报表导出] │
└─────────────────────────────────────────────────────────────────────────┘报警级别与联动动作:
┌─────────────────────────────────────────────────────────────────────┐
│ 级别 │ 条件 │ 联动动作 │
├───────┼─────────────────────────┼──────────────────────────────────┤
│ 提示 │ 湿度偏离目标 > 3%RH │ 画面提示,记录日志 │
│ │ 持续 5 分钟 │ │
├───────┼─────────────────────────┼──────────────────────────────────┤
│ 预警 │ 湿度偏离目标 > 5%RH │ 弹窗 + 声音 + 短信通知运维 │
│ │ 持续 10 分钟 │ 自动加大控制输出 │
├───────┼─────────────────────────┼──────────────────────────────────┤
│ 报警 │ 湿度 < 40% 或 > 65% │ 弹窗 + 声音 + 短信 + 电话 │
│ │ 持续 5 分钟 │ 启动所有备用设备 │
│ │ │ 关闭新风/排风 │
├───────┼─────────────────────────┼──────────────────────────────────┤
│ 紧急 │ 温度 > 30℃ 或 < 10℃ │ 消防联动级别 │
│ │ 或湿度 > 75% 持续 1h │ 关闭所有恒湿设备 │
│ │ │ 启动应急通风 │
│ │ │ 通知档案管理人员紧急处置 │
├───────┼─────────────────────────┼──────────────────────────────────┤
│ 设备 │ 恒湿机故障 │ 弹窗 + 短信 │
│ │ │ 自动切换到备用设备 │
│ │ │ 记录故障代码和时间 │
├───────┼─────────────────────────┼──────────────────────────────────┤
│ 通信 │ 传感器离线 > 30s │ 画面标记灰色 │
│ │ │ 如果该分区离线 > 50% 测点 │
│ │ │ → 该分区切换为相邻分区均值代替 │
└─────────────────────────────────────────────────────────────────────┘
报警回滞(防抖):
湿度报警恢复条件:
一级预警(>53%RH 触发):回落到 ≤51%RH 才恢复
二级报警(>55%RH 触发):回落到 ≤52%RH 才恢复
三级紧急(>65%RH 触发):回落到 ≤58%RH 才恢复
原因:湿度变化慢,如果不设回滞,会在阈值附近反复触发/恢复项目 | 标准 | 测试方法 |
|---|---|---|
湿度控制精度 | ±3%RH(长期均值) | 连续运行 7 天,统计各分区均值 |
湿度均匀性 | 各分区极差 ≤ 5%RH | 同时读取所有传感器,计算极差 |
温度控制精度 | ±1℃ | 同上 |
控制响应时间 | 湿度偏差 >5%RH 后 30min 内开始收敛 | 人为制造偏差,计时 |
超调量 | ≤ 3%RH | 阶跃测试(改变设定值 5%RH) |
设备切换时间 | ≤ 5min(故障切换) | 模拟设备故障,计时 |
通信中断恢复 | ≤ 30s 自动重连 | 拔网线测试 |
数据到达率 | ≥ 99.9% | 72h 连续运行统计 |
报警响应 | < 30s | 模拟越限,计时 |
历史数据完整性 | 无断点 ≥ 99.5% | 检查历史数据库 |
档案库房微环境调控的本质,是用分布式传感器网络构建空间感知能力,用 PID + 模糊规则实现平滑控制,用多设备协同调度避免内耗,用组态软件提供可视化决策界面。 传感器不只是"读数工具",而是整个调控闭环的"眼睛"——没有准确、密集、实时的感知,再好的恒湿设备也只是在盲目运转。
关键词:档案库房、微环境调控、闭环控制、恒湿设备、PID控制、模糊规则、传感器驱动、分区控制、空间加权均值、湿度均匀性、Modbus TCP、边缘控制引擎、组态联动、防振荡、设备调度、GB/T 27703
标签:#档案库房 #微环境调控 #闭环控制 #恒湿设备 #PID控制 #模糊规则 #传感器驱动 #分区控制 #空间加权均值 #湿度均匀性 #ModbusTCP #边缘控制 #组态联动 #防振荡 #设备调度 #GB/T27703 #十防监控
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。