首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >档案馆环境监测实战:温湿度传感器组网、恒温恒湿设备组态对接

档案馆环境监测实战:温湿度传感器组网、恒温恒湿设备组态对接

原创
作者头像
HONSOR盛世宏博
发布于 2026-09-23 13:12:31
发布于 2026-09-23 13:12:31
800
举报

档案馆环境监测实战:温湿度传感器组网、恒温恒湿设备组态对接

一、实战语境:从"能通"到"可运维"

前几篇覆盖了控制闭环、故障排查、老旧馆改造。本文收口到落地前的最后一段工程:传感器怎么组网上线、恒温恒湿设备怎么组态接入。重点不在原理,在交付现场反复踩的那几件事——IP 规划、PoE 预算、Modbus 点表、BACnet 对象映射、DDC 组态、联调验证。目标是让一套系统从出厂状态走到可运行、可纳管、可回滚。

二、温湿度传感器组网

2.1 拓扑与分段

档案馆场景典型拓扑:

代码语言:javascript
复制
核心/汇聚交换机
   │  VLAN 10 业务网(平台、Grafana、InfluxDB)
   │  VLAN 20 动环/暖通网(传感器、DDC、网关)
   │  VLAN 30 设备网(机组控制器、BACnet/IP)
   ▼
接入交换机(PoE+)——边缘采集网关/容器宿主机
   ├── 网口温湿度变送器(Modbus TCP,502)
   ├── DDC/PLC(Modbus TCP / BACnet/IP)
   └── IO 扩展模块(Modbus TCP / RTU 转 TCP)
  • 监控网与业务网隔离,跨 VLAN 经防火墙/ACL 放行 502、47808(BACnet)、1883(MQTT)、8086(InfluxDB)。
  • 边缘采集网关就近部署,减少跨交换机广播域;多库时分片采集,避免单点轮询过载。
  • 物理层:Cat5e/6 到信息点,PoE 供电时核算线径与距离,100m 上限内留余量,超距走光纤+PoE 延伸器。

2.2 IP 规划与命名

  • 固定 DHCP 保留或静态分配,别让传感器漂 IP。建议规划表:

区域

VLAN

网段

端口组

描述

A 库

20

10.20.1.0/24

PoE1-1~12

回风2+工作区4+角落2

B 库

20

10.20.2.0/24

PoE2-1~8

同上

DDC

20

10.20.0.0/24

管理口+控制口

双网卡或单臂按厂定

网关

20/10

10.20.0.250

trunk

采集+上行

  • 命名规范:zone-loc-type-id,如 A-ret-htu-01、B-ws-htu-03。平台侧 device_id 与此绑定,避免后期排障时对着 IP 发呆。
  • DNS 可选,但建议 mDNS/LLDP 关闭或收敛,防止广播干扰老旧 DDC。

2.3 PoE 预算核算

别按端口数乘单口功耗算,按交换机池算:

代码语言:javascript
复制
交换机 PoE 预算 P_budget(W)
Σ 端口分配 = Σ(device_poe_load × 1.2 余量)
预留 ≥20% headroom 给启动冲击和扩展
  • 网口温湿度变送器典型 1.5~3W,但 PoE 协商后 PSE 按 class 供电,需确认 PD 支持 802.3af/at。
  • 高密度布点时,接入交换机 PoE 控制器过热降额,现场实测满载时电源余量。
  • 非 PoE 传感器走外部 DC 电源时,电源回路单独保护,别与执行器共回路。

2.4 上线流程

  1. 出厂预配置:出厂前批量烧录 IP/掩码/网关/Modbus 单元号,或到现场经串口/Web 配置。保留配置模板。
  2. 单点上电测试:每台接 PoE 端口,确认链路 up、LLDP 可见、Web/CLI 可读。
  3. 组播/广播域检查:确认无 IP 冲突、无 DHCP 误分配。
  4. 批量注册:采集服务发现或手动导入设备表,建立 device_id↔IP↔点表版本映射。
  5. 采样验证:连续 15min 拉取,确认时标、单位、质量位。
  6. 布点复核:回风口必装,工作区 1.5m 高,离墙≥0.5m,避开直吹/阳光/热源;特藏库加密。

2.5 采集侧参考实现

代码语言:javascript
复制
"""
poll_env.py - 边缘采集服务参考实现(精简版)
- 分片轮询 Modbus TCP 设备,归一化后批量写 InfluxDB,并上行 MQTT
- 生产环境需补:重连、退避、质量位、配置热加载、健康上报
"""

import asyncio, signal
from collections import defaultdict
from pymodbus.client import AsyncModbusTcpClient
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS

DEVICES = {
    "A-ret-htu-01": {"host": "10.20.1.11", "unit": 1, "regs": {"t": (0,1), "h": (1,1)}},
    "A-ws-htu-02":  {"host": "10.20.1.12", "unit": 1, "regs": {"t": (0,1), "h": (1,1)}},
    # ...
}

POLL_INT = 5.0  # s
INFLUX = {"url": "http://localhost:8086", "token": "...", "org": "arch", "bucket": "env"}

def scale_temp(raw):   # 依厂家表:0.1℃ 定点,有符号
    return raw / 10.0
def scale_hum(raw):
    return raw / 10.0

class Collector:
    def __init__(self):
        self.clients = {}
        self.influx = InfluxDBClient(url=INFLUX["url"], token=INFLUX["token"], org=INFLUX["org"])
        self.write_api = self.influx.write_api(write_options=SYNCHRONOUS)

    async def client_for(self, host):
        if host not in self.clients:
            c = AsyncModbusTcpClient(host)
            await c.connect()
            self.clients[host] = c
        return self.clients[host]

    async def poll_dev(self, dev_id, cfg):
        try:
            c = await self.client_for(cfg["host"])
            if not c.connected:
                await c.connect()
            # 批量读保持寄存器(示例:t,h 连续两个寄存器)
            rr = await c.read_holding_registers(0, 2, slave=cfg["unit"])
            if rr.isError():
                return self.emit(dev_id, None, False)
            raw_t, raw_h = rr.registers
            t = scale_temp(raw_t); h = scale_hum(raw_h)
            self.emit(dev_id, {"temperature": t, "humidity": h}, True)
        except Exception as e:
            self.emit(dev_id, None, False, err=str(e))

    def emit(self, dev_id, val, ok, err=None):
        zone = dev_id.split("-")[0]
        p = Point("env").tag("device", dev_id).tag("zone", zone)
        if ok and val:
            p = p.field("temperature", val["temperature"]).field("humidity", val["humidity"]).field("quality",1)
        else:
            p = p.field("quality",0)
        self.write_api.write(bucket=INFLUX["bucket"], org=INFLUX["org"], record=p)
        # 上行 MQTT(略)

    async def run(self):
        while not self._stop:
            for dev_id, cfg in DEVICES.items():
                await self.poll_dev(dev_id, cfg)
            await asyncio.sleep(POLL_INT)

    def stop(self):
        self._stop = True

if __name__ == "__main__":
    col = Collector()
    loop = asyncio.get_event_loop()
    loop.add_signal_handler(signal.SIGTERM, col.stop)
    try:
        loop.run_until_complete(col.run())
    finally:
        loop.run_until_complete(asyncio.sleep(0))

注意点:

  • 异步轮询时别对单设备阻塞过久,超时设短(1~2s),失败快速退化。
  • 寄存器表版本化管理:设备固件升级后偏移/字序/缩放可能变,配置与代码解耦,外置 YAML。
  • 批量规模大时,分库分片 + 连接池,别所有设备共用单 TCP 连接串行轮询。

三、恒温恒湿设备组态对接

3.1 先分清对接边界

设备侧

对接方式

平台侧职责

精密空调/恒湿机组,带通信卡

Modbus TCP / BACnet/IP / 厂家 SDK

读状态、写下发设定值、收告警

DDC/PLC 自研控制逻辑

Modbus TCP 保持寄存器/线圈、BACnet 对象

监督控制,不直接驱执行器

传统机组无通信

DO/AI 扩展模块 + DDC

现场闭环,平台监状态

第三方 BA 系统

网关桥接 / OPC-UA / BACnet 路由

点表映射进统一模型

关键:组态不在平台 UI 里画逻辑,而在现场控制器/DDC 工程文件里。平台拿到的是监督接口。

3.2 Modbus TCP 组态

  1. 拿到寄存器表:向机组厂要正式点表,确认:
    • 寄存器区(保持寄存器 4x / 输入寄存器 3x)、偏移基址(0-based vs 1-based)
    • 数据类型(16bit/32bit IEEE754 浮点/定点缩放)、字序(big/little endian)、符号
    • 线圈/离散量地址(启停、故障复位、模式选择)
    • 写保护:写线圈还是写保持寄存器?有的厂只开放只读,启停走硬接线/面板
  2. DDC/网关侧组态:
    • 建变量表,绑定 Modbus 从站地址、功能码、寄存器、数据类型、扫描周期
    • 建任务/POU:读周期 1s~5s,写回差处理,故障字解析
    • 控制程序:PID 回路、模式切换、轮换调度、防冷凝保护
  3. 平台侧组态:
    • 设备模型:device、subsystem=hvac、points=[setpoint_temp, setpoint_hum, mode, run_state, fault_word, ret_temp, ret_hum…]
    • 映射层:Modbus 点→平台点,版本号绑定
    • 写策略:平台下发目标带/设定值,DDC 执行;写操作鉴权、限幅、确认回读
  4. 联调:
    • 开环:手动置设定值,确认 DDC 响应、机组动作
    • 半闭环:DDC 本地闭环,平台只读
    • 监督闭环:平台改目标带,验证 DDC 跟随

3.3 BACnet/IP 组态

  1. 设备发现:bacwi/YABE 发现设备,记录 device-id、object-list。
  2. 对象映射:
    • analog-input(回风温湿度)、analog-output/analog-value(设定值、阀位)、binary-value(启停、模式)、event-notification/alarm-summary
    • 确认 present-value 可读写、priority-array 不被更高优先级覆盖
  3. DDC/网关侧:BACnet 服务端还是客户端?
    • 多数 DDC 原生 BACnet 服务端,平台经 BACnet 客户端读写
    • 老机组经网关转协议,网关做 BACnet 服务端,DDC 做客户端轮询,或反之
  4. BBMD/广播管理:跨 VLAN 时 BACnet 广播发现失效,配 BBMD 或静态设备绑定。
  5. 联调:who-is/i-am、read-property、write-property 验证;注意写优先级和回落默认值。

3.4 DDC 组态落地要点

  • 变量规划:I/O 点表、内部变量、通信变量分域,避免全局变量满天飞。
  • 任务周期:通信任务、控制任务、HMI 任务分离,控制任务周期固定(如 500ms)。
  • 故障字解析:位域展开成内部报警态,进告警总线;别在平台侧解析裸字。
  • 模式管理:手动/自动/维护旁路/应急降级,状态机明确迁移条件。
  • 执行器行程校验:输出前确认阀位反馈回读,未回读时降级到安全态。
  • 持久化:DDC 掉电保持最后设定值、运行模式、轮换计数;恢复后不回出厂默认。
  • 安全联锁:消防状态介入时,暖通执行受抑,平台只监不控。

3.5 组态版本与回滚

  • DDC 工程文件、点表 YAML、平台映射表、固件版本,四者版本绑定。
  • 变更流程:离线改→仿真/实验室验→灰度下发→现场确认→回滚点留档。
  • 回滚:配置错误时 5min 内恢复到上一可用版本,别现场手工改参数凑合。

四、联调与验证

4.1 开环验证清单

  • [ ] 每传感器可读,值合理,时标正确
  • [ ] 每执行器可手动触发,状态回读正确
  • [ ] Modbus/BACnet 点表与现场一致,无地址错位
  • [ ] PoE 端口供电正常,满载无降额
  • [ ] 网络 ACL 放行,跨 VLAN 连通性确认

4.2 半闭环验证

  • DDC 本地自动模式运行,平台只读监视
  • 注入扰动(开门、加热器),观察 PID 跟踪、回风反馈、阀位变化
  • 确认防冷凝保护独立触发,再热/风阀联动正确

4.3 监督控制验证

  • 平台改目标带/设定值,DDC 跟随,回读确认
  • 轮换调度:主备切换,运行计时均衡
  • 故障注入:断网、DDC 重启、机组停机、传感器拔线
  • 恢复后补传、配置持久化、状态机回到原模式

4.4 现场抓包定位组态问题

代码语言:javascript
复制
# Modbus TCP 交互
tcpdump -i eth0 -nn 'host 10.20.1.11 and port 502' -w /tmp/mb.pcap
# BACnet
tcpdump -i eth0 -nn 'port 47808' -w /tmp/bac.pcap
# 连通性/ACL
nmap -p 502,47808 10.20.x.x

Wireshark 过滤:modbus、bacnet。重点看:

  • Modbus:事务ID是否匹配、异常响应码(0x83+异常子码)、长度字段、字节序
  • BACnet:ConfirmedServiceRequest/ReadProperty/WriteProperty、abort/reject、priority
  • TCP 层:RST、零窗口、长连接断开后未重连

五、常见组态坑

  1. 寄存器基址错配:厂家表 40001,代码填 offset 0 还是 1,pymodbus 用 0-based,现场踩两次。
  2. 32bit 值拆字:温湿度设定值浮点跨两寄存器,字序错读成 NaN。
  3. 缩放因子遗漏:原始值 201=20.1℃ 还是 2010?文档不写清就现场标定。
  4. 写操作无回读:下发成功≠执行器动,DDC 未映射写对象,平台以为已控。
  5. BACnet 优先级被覆盖:写 analog-value 后被本地程序每周期刷回。
  6. DDC 任务周期过长:通信 5s+控制 1s,扰动下跟踪滞后,误判振荡。
  7. PoE 交换机 VLAN 透传错:Trunk 口 native VLAN 错,传感器落到管理网。
  8. 断网后 DDC 自治未使能:平台回来发现机组停摆,因通信丢失时进安全停机而非维持。
  9. 点表版本漂移:固件升级后对象表变,映射未同步,静默错值。
  10. 告警风暴:未去抖、未做抑制窗,调试期刷屏,运维关告警——反而漏真故障。

六、交付物清单

  • 网络拓扑图 + VLAN/IP 规划表 + PoE 预算表
  • 设备清单 + 固件版本 + 通信卡型号
  • Modbus 寄存器表 / BACnet 对象表(版本化)
  • DDC 工程文件 + 变量表 + 控制逻辑说明
  • 平台点表映射配置 + 采集服务配置 + MQTT/InfluxDB schema
  • 联调记录 + 故障注入记录 + 回滚预案
  • 运维 SOP + 校准台账接口

七、小结

组网侧:IP/VLAN/PoE/采集分片,上线前单点验证再批量注册;组态侧:边界分清——现场 DDC 跑闭环,平台跑监督,点表版本化,联调逐级放开。交付完成度看三件事:采样可信、组态可回滚、联动可验证。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 档案馆环境监测实战:温湿度传感器组网、恒温恒湿设备组态对接
    • 一、实战语境:从"能通"到"可运维"
    • 二、温湿度传感器组网
      • 2.1 拓扑与分段
      • 2.2 IP 规划与命名
      • 2.3 PoE 预算核算
      • 2.4 上线流程
      • 2.5 采集侧参考实现
    • 三、恒温恒湿设备组态对接
      • 3.1 先分清对接边界
      • 3.2 Modbus TCP 组态
      • 3.3 BACnet/IP 组态
      • 3.4 DDC 组态落地要点
      • 3.5 组态版本与回滚
    • 四、联调与验证
      • 4.1 开环验证清单
      • 4.2 半闭环验证
      • 4.3 监督控制验证
      • 4.4 现场抓包定位组态问题
    • 五、常见组态坑
    • 六、交付物清单
    • 七、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档