尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Modbus TCP/UDP与SNMP融合的楼宇温湿度监测系统实践

发布时间:2026/9/26 11:21:49

资讯中心
01
ARTICLE

Modbus TCP/UDP与SNMP融合的楼宇温湿度监测系统实践

Modbus TCP/UDP与SNMP融合的楼宇温湿度监测系统实践
1. 系统整体设计为什么是Modbus TCP/UDP加上SNMP做楼宇自控的人都知道温湿度监测看着是个小活真正落地却涉及协议选型、设备接入、网络规划一堆事。传统方案里很多老楼用的是RS485走Modbus RTU一条总线挂几十个探头手拉手串下去施工麻烦不说一旦某个节点故障后面整条链路都可能瘫痪。这套基于Modbus TCP/UDP加SNMP的方案本质上就是想把传感器采集和网络设备状态监测统一到一张IP网络上减少布线成本同时让运维人员在一套系统里同时看到环境温湿度和网络设备健康状况两类数据。我最早接触这个需求是因为一个中型园区的机房和弱电间改造。甲方提了两个要求一是每个弱电间、配电间、机房都要有温湿度监测数据要进楼宇自控平台二是希望知道交换机、服务器这些网络设备的在线状态和负载情况不想再单独部署一套网管软件。两个要求分开做都不难难在合并成一套系统。Modbus TCP/UDP天生适合采集温湿度传感器数据SNMP则是网络设备管理的标准协议两者都基于IP网络完全可以在一个采集网关里共存。这就是整套系统的设计出发点一套采集平台两种协议三类数据温湿度、设备在线、设备负载。这个方案适合谁参考如果你是做楼宇自控集成、机房动环监控、园区弱电运维的工程师尤其是手里已经有一批支持Modbus TCP的传感器又不想额外买商业网管软件的场景这篇文章分享的架构和踩坑经验应该能省你不少调试时间。系统架构其实可以拆成四层感知层温湿度传感器支持Modbus TCP或UDP放置在弱电间、机房、配电间、库房等需要监测的位置。接入层采集网关或直接用支持Python/Node-RED的工业边缘网关负责轮询传感器数据。网络层管理型交换机支持SNMP提供网络拓扑和端口状态信息。应用层楼宇自控平台或自建的Web监控界面汇总展示数据做告警。我自己的落地配置是传感器用建大仁科或同类的工业级Modbus TCP温湿度探头采集网关用一台x86工控机跑Linux系统写Python脚本做采集和协议转换SNMP部分直接通过网关的snmpwalk去读华为交换机的OID。这套组合成本不高灵活度却很高。为什么要选Modbus TCP/UDP而不是继续用RTU核心原因是布线成本和故障隔离。Modbus RTU走RS485一条总线上的设备共享带宽轮询一个周期的时间会随设备数量线性增加而且485总线是半双工的接线极性反了、终端电阻没配好都会导致整条总线通信异常排查起来非常痛苦。Modbus TCP走以太网每个传感器独立IP点对点通信一个设备故障不会影响其他设备也天然支持跨楼层、跨建筑的IP网络传输。至于UDP它比TCP少了连接维护的开销适合数据上报频率低、允许偶尔丢包的场景比如温度变化本来就很慢10秒丢一两个包根本无感用UDP反而更轻量。2. 核心细节解析与实操要点2.1 Modbus TCP帧结构里容易被忽略的三个细节Modbus TCP的报文结构很简单报文头MBAP Header 功能码 数据。MBAP Header共7个字节包含事务处理标识符2字节、协议标识符2字节、长度2字节、单元标识符1字节。很多新手会忽略单元标识符——在同一台网关要跨多个串口采集设备时这个字段是用来区分设备链路的但在纯Modbus TCP场景下一般填0x01就行。功能码方面温湿度传感器绝大多数支持03读保持寄存器和04读输入寄存器。不同厂家的传感器数据存放的功能码不一样甚至同一个厂家不同批次的产品都可能不同。我遇到过一款传感器温度存放在输入寄存器功能码04湿度存放在保持寄存器功能码03调试时必须分开读不能一次批量读取。所以拿到新传感器第一步永远是翻手册搞清楚寄存器映射表而不是盲目写轮询代码。第二个容易踩坑的是寄存器数据类型。绝大多数温湿度传感器的温度和湿度是用16位整数表示的需要除以10或100才是实际值。但也有的传感器用两个寄存器拼一个32位浮点数高位在前还是低位在前不同厂家实现还不一样。我见过最坑的是某品牌传感器32位浮点数的字节序是小端序而Modbus协议默认是大端序直接解析出来温度显示成负数排查了很久才发现是字节序问题。第三个细节是轮询周期的设置。Modbus TCP虽然没有总线冲突问题但传感器本身有处理能力上限尤其是便宜的工业传感器内部MCU主频很低网关如果以100ms的间隔去轮询传感器会来不及响应出现超时。我一般把轮询周期设成2秒到5秒对于温湿度这种缓变信号完全够用。如果传感器数量多比如超过50个建议把轮询周期拉长到10秒或者分成多个线程分组轮询。核心原则是采集数据的频率要匹配物理量的变化速度温度不可能在1秒内跳变5度没必要高频轮询。2.2 SNMP协议的核心概念与华为交换机配置要点SNMP协议的核心是OID对象标识符可以理解为网络设备内部信息的一棵目录树。想要读取交换机的CPU利用率、内存使用率、端口状态、温度本质就是找到对应的OID节点然后发起GET请求。SNMP有三个版本v1基本废弃了v2c增加了批量获取v3增强了安全性。楼宇自控这类内网环境通常用v2c就够但要注意Community字符串相当于密码不要用默认的public容易被内网其他设备扫描到。华为交换机的SNMP配置用命令行几行就能搞定system-view snmp-agent snmp-agent community read cipher your_community_name snmp-agent sys-info version v2c snmp-agent target-host trap-addressudp-address 192.168.1.100 params securityname your_community_name第一行是启用SNMP代理第二行设置只读共同体第三行指定协议版本第四行配置Trap告警上报地址。这里的Trap是SNMP的主动上报机制设备发现异常时主动往监控平台发消息不需要平台轮询。对于温湿度监测系统Trap可以用来上报交换机的温度过高告警、端口up/down事件和温湿度传感器的联动非常有价值——比如机房空调故障导致环境温度升高交换机温度也会同步上升两边的告警可以相互印证。配置完后测试连通性在网关机器上执行snmpwalk -v2c -c your_community_name 192.168.1.254 1.3.6.1.4.1.2011这个OID段是华为企业的私有MIB库根节点。如果命令返回一堆信息说明SNMP配置成功。如果返回超时先ping试试网络通不通再确认交换机的ACL有没有拦截SNMP报文。我碰到过一次交换机配置了管理ACL只允许特定IP访问网关不在允许列表里导致snmpwalk超时排查了很久才想起来ACL这层。2.3 网关数据汇聚从Modbus到SNMP的桥接思路网关在整个系统中的角色是翻译官上午用Modbus TCP轮询传感器拿到温度值下午用SNMP读交换机OID拿到端口状态最后把所有数据统一成一种格式向上层平台推送。这个桥接思路可以用一张简单的表来理解数据源协议采集方式典型周期温湿度传感器Modbus TCP/UDP网关主动轮询2-5秒交换机CPU/内存SNMP v2c网关主动轮询30-60秒交换机端口状态SNMP v2c网关轮询 Trap接收30秒 实时告警事件SNMP Trap被动接收实时为什么交换机状态用30秒甚至60秒的轮询周期因为CPU利用率、端口流量这类数据本身就在波动频繁采样没有意义而且SNMP的GET操作在交换机上也是要消耗CPU资源的监控频率太高会干扰设备的正常工作。温湿度传感器则是毫秒级响应、数据变化慢用2-5秒的周期既能保证及时性又不会给设备造成负担。网关的数据处理逻辑我通常这样设计独立的采集线程池每个传感器一个线程避免一个传感器的超时阻塞拖累其他传感器数据统一打上时间戳存到内存缓存里每5秒刷一次数据库SNMP采集线程独立运行30秒一次没有数据更新就用上一次的值。这套设计的关键是隔离故障域Modbus的某台传感器掉线只影响它自己的线程网关照常运行。3. 实操过程与核心环节实现3.1 传感器选型和物理部署温湿度传感器的选型我总结了几条经验精度要求机房和弱电间一般要求温度±0.5℃湿度±3%RH普通的工业传感器都能满足。如果甲方是计量实验室或药品库房需要选更高精度的传感器价格会贵不少。供电方式优先选POE供电的型号不用单独拉电源线一根网线搞定通信和供电。如果没有POE交换机就得选DC 12V供电的传感器部署时要考虑电源适配器的位置。探头形式壁挂式适合安装在弱电间墙壁1.5米高度管道式适合安装在空调送风管或回风管里测的是风温吸顶式适合机房吊顶空间。不同场景选不同形式别一刀切。物理部署时有个细节传感器不要安装在空调出风口正下方或窗户旁边测出来的温度没有代表性也就是所谓局部热岛效应。我在一个配电间就踩过这个坑传感器正好在空调回风口旁边夏天温度显示23℃实际柜内温度已经28℃了空调失效了都没触发告警。后来把传感器移到机柜背板上方的回风区域才真正反映出设备发热状况。3.2 Modbus TCP采集代码的完整实现下面是我在网关设备上跑的一段Python采集脚本兼容Modbus TCP和UDP两种模式注释都标得很清楚import socket import struct import threading import time import json from datetime import datetime MODBUS_TCP_PORT 502 # 事务ID(2字节) 协议ID(2字节) 长度(2字节) 单元ID(1字节) 7字节头 MBAP_HEADER_LEN 7 # 03功能码读保持寄存器04是读输入寄存器 READ_HOLDING_REGISTERS 0x03 READ_INPUT_REGISTERS 0x04 class ModbusSensor: def __init__(self, ip, name, reg_addr, count2, register_type0x03, data_formatint16, scale0.1, use_udpFalse, unit_id1): self.ip ip self.name name self.reg_addr reg_addr self.count count self.register_type register_type self.data_format data_format self.scale scale self.use_udp use_udp self.unit_id unit_id self.latest_value None self.connected False self._lock threading.Lock() self._sock None def _create_socket(self): 创建TCP或UDP socketUDP模式不需要建立连接 if self.use_udp: sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(2) else: sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(3) sock.connect((self.ip, MODBUS_TCP_PORT)) return sock def _build_request(self, transaction_id): 构造Modbus请求报文 length 6 # 单元ID 功能码 起始地址2字节 寄存器数量2字节 header struct.pack(HHHB, transaction_id, 0, length, self.unit_id) pdu struct.pack(BHH, self.register_type, self.reg_addr, self.count) return header pdu def _parse_response(self, resp): 解析Modbus响应报文重点关注寄存器数值 if len(resp) MBAP_HEADER_LEN 3: raise ValueError(f响应报文长度异常: {len(resp)}) func_code resp[7] byte_count resp[8] if func_code 0x80: # 异常标志位 exception_code resp[9] raise ValueError(fModbus异常码: {exception_code}) # 寄存器值从第9字节开始每寄存器2字节 regs [] for i in range(byte_count // 2): offset 9 i * 2 regs.append(struct.unpack(H, resp[offset:offset2])[0]) return regs def read_once(self): 执行一次读取处理字节序和缩放 try: if self._sock is None: self._sock self._create_socket() transaction_id int(time.time() * 1000) % 65535 req self._build_request(transaction_id) if self.use_udp: self._sock.sendto(req, (self.ip, MODBUS_TCP_PORT)) resp, _ self._sock.recvfrom(256) else: self._sock.send(req) resp self._sock.recv(256) regs self._parse_response(resp) if self.data_format int16: # 温度通常为有符号16位整数需要按2的补码转换 raw regs[0] if regs[0] 32768 else regs[0] - 65536 value raw * self.scale elif self.data_format float32_be: # 大端32位浮点数两个寄存器拼一个float packed struct.pack(HH, regs[0], regs[1]) value struct.unpack(f, packed)[0] elif self.data_format float32_le: # 小端32位浮点数 packed struct.pack(HH, regs[0], regs[1]) packed packed[2:] packed[:2] value struct.unpack(f, packed)[0] else: value regs[0] * self.scale with self._lock: self.latest_value value self.connected True return value except Exception as e: with self._lock: self.connected False # 掉线时关闭socket下次读取会自动重连 if self._sock: self._sock.close() self._sock None raise e def poll_loop(self, interval5): 持续轮询线程入口 while True: try: val self.read_once() print(f[{datetime.now()}] {self.name}: {val}) except Exception as e: print(f[{datetime.now()}] {self.name} 读取失败: {e}) time.sleep(interval) def main(): sensors [ ModbusSensor(192.168.1.101, 弱电间-3F-温湿度, reg_addr0, count2, register_typeREAD_INPUT_REGISTERS, data_formatint16, scale0.1), ModbusSensor(192.168.1.102, 机房-A区-温湿度, reg_addr1, count2, register_typeREAD_HOLDING_REGISTERS, data_formatint16, scale0.1), ] for sensor in sensors: t threading.Thread(targetsensor.poll_loop, args(5,), daemonTrue) t.start() # 主线程等待子线程实际项目中可在这里做数据入库或Web推送 while True: time.sleep(10) if __name__ __main__: main()这段代码有几个细节值得说一是UDP模式复用同一个socket靠transaction_id区分响应实际使用中传感器地址是唯一的不存在多设备冲突可以简单处理二是TCP模式如果断线了不要反复重试同一个socket直接把socket关了下次轮询重新连接避免TCP半开连接挂在那里三是int16转有符号数时别忘了负值的补码转换冬天温度或者冷库场景会出现负数处理不对会显示成65535这样的巨大值。3.3 SNMP采集与Trap接收的完整实现SNMP部分我用pysnmp库来实现它是纯Python的SNMP协议栈比调系统自带的snmpget命令要灵活和Modbus采集逻辑放在同一个进程里完全没毛病from pysnmp.hlapi import * OIDS { huawei_cpu_usage: 1.3.6.1.4.1.2011.5.25.31.1.7.1.3.0, huawei_mem_usage: 1.3.6.1.4.1.2011.5.25.31.1.8.1.1.0, sys_uptime: 1.3.6.1.2.1.25.1.1.0, device_temp: 1.3.6.1.4.1.2011.5.25.31.1.7.1.2.0, } def snmp_get(host, community, oid, port161): 获取单个OID的值 error_indication, error_status, error_index, var_binds next( getCmd(SnmpEngine(), CommunityData(community, mpModel1), # mpModel1表示SNMPv2c UdpTransportTarget((host, port), timeout3, retries1), ContextData(), ObjectType(ObjectIdentity(oid))) ) if error_indication: raise RuntimeError(fSNMP错误: {error_indication}) if error_status: raise RuntimeError(fSNMP错误状态: {error_status}) for var_bind in var_binds: return var_bind[1].prettyPrint() def snmp_walk(host, community, base_oid, port161): 遍历某个OID子树下所有节点用于获取端口列表等信息 results [] for error_indication, error_status, error_index, var_binds in \ nextCmd(SnmpEngine(), CommunityData(community, mpModel1), UdpTransportTarget((host, port), timeout3, retries1), ContextData(), ObjectType(ObjectIdentity(base_oid)), lexicographicModeFalse): if error_indication: break if error_status: break for var_bind in var_binds: oid_str var_bind[0].prettyPrint() value var_bind[1].prettyPrint() results.append((oid_str, value)) return results def snmp_trap_receiver(port162, communityyour_community): 接收SNMP Trap告警华为主机名、IP、告警内容都会带过来 # 实际使用中可用snmp engine加Callback来处理这里示意 pass def collect_switch_metrics(switches): 批量采集交换机状态数据 for sw in switches: try: cpu snmp_get(sw[ip], sw[community], OIDS[huawei_cpu_usage]) mem snmp_get(sw[ip], sw[community], OIDS[huawei_mem_usage]) temp snmp_get(sw[ip], sw[community], OIDS[device_temp]) packet { ip: sw[ip], name: sw.get(name, sw[ip]), cpu_usage: cpu, mem_usage: mem, device_temp: temp, timestamp: time.time() } print(json.dumps(packet, ensure_asciiFalse)) except Exception as e: print(f采集 {sw[ip]} 失败: {e}) if __name__ __main__: switches [ {ip: 192.168.1.254, community: your_community, name: S5735-核心}, {ip: 192.168.2.254, community: your_community, name: S5735-接入}, ] collect_switch_metrics(switches)华为主流设备的OID基本稳定但不同型号、不同固件版本会有差异。比如CPU利用率的OID在某些老型号上是 1.3.6.1.4.1.2011.6.3.4.1.4.0新版本就换成了 1.3.6.1.4.1.2011.5.25.31.1.7.1.3.0。调试的时候先手动snmpwalk一下确认OID有效再写进代码里面去。我一般会在系统上线前列一个清单哪台设备、哪个OID、期望值是什么逐项核对。3.4 数据关联与告警联动设计真正让这套系统产生价值的是数据关联。单独的温湿度数据和单独的CPU数据其实是孤岛但把时间轴对齐后就能看出因果关系。我设计过这样一个告警联动逻辑当机房的温度传感器读数超过28℃同时交换机CPU利用率超过80%判定为设备过热可能导致计算瓶颈告警等级提高。当某弱电间的湿度超过70%RH同时对应交换机端口出现大量crc错误包判定为网络链路可能因潮湿导致信号质量下降通知运维去排查物理链路。当传感器通信中断超过5分钟同时交换机端口状态显示该设备所接端口为down判定为传感器或线缆故障排除是传感器自身离线还是交换机端口崩溃。这套联动逻辑用简单的规则引擎就能跑不需要复杂的大数据模型但效果非常直接。有一次机房空调故障温湿度传感器在5分钟内就测到温度从24℃升到31℃而交换机设备温度也从45℃升到58℃还没到告警阈值。传统做法是等交换机温度告警了才去看一番而联动逻辑就把两个数据放在了一起直接提示环境温度异常导致设备温度升高运维不用猜原因直接奔空调去检查。这就是两类协议一起接入的价值。3.5 数据库与可视化数据落库我用的是最简单的SQLite加定时导出CSV的方案单体项目足够了。每5秒写一条温湿度记录30秒写一条交换机状态记录。数据库表结构设计CREATE TABLE sensor_data ( id INTEGER PRIMARY KEY AUTOINCREMENT, sensor_ip TEXT NOT NULL, sensor_name TEXT, temperature REAL, humidity REAL, reading_time INTEGER ); CREATE TABLE switch_metrics ( id INTEGER PRIMARY KEY AUTOINCREMENT, switch_ip TEXT NOT NULL, switch_name TEXT, cpu_usage REAL, mem_usage REAL, device_temp REAL, reading_time INTEGER );可视化我图省事直接在网关上面跑了一个轻量的Web服务用ECharts画曲线。温度曲线、湿度曲线、CPU曲线、设备温度曲线外加一个告警列表页面。不要一上来就上Grafana或者商业楼宇平台先用简单的方式验证数据和告警逻辑是否可靠再考虑迁移到完整平台上这样迭代成本低不少。4. 常见问题与排查技巧实录4.1 Modbus通信类问题传感器可以ping通但Modbus读取超时。优先检查是否开启了防火墙拦截502端口。我遇到过Windows防火墙默认拦截外部连接的情况换成Linux工控机后还要确认selinux没有拦截。其次看传感器是否有连接数限制有些廉价传感器只支持2-3个TCP连接如果同时被多个调试工具连接新的采集请求就会被拒绝。排查时可以先断开其他客户端只留网关一个连接测试。读到的温度数值明显偏高或偏低。先确认寄存器地址是否正确。很多传感器在0号寄存器放温度、1号寄存器放湿度但有的型号0号寄存器放的是设备状态字要用寄存器映射表逐个核对。另外注意缩放系数有传感器温度直接是整数摄氏度不用除以10有的是0.01精度要除以100。不能凭经验猜必须以手册为准。部分传感器读取正常个别传感器在固定地址上超时。这种情况多半是传感器IP冲突。用arp扫描一下同网段IP确认没有两个设备占用同一个IP。另外检查弱电间的交换机端口是否开启了端口隔离导致网关与传感器不在同一个广播域里ping不通的传感器一定检查接入交换机的VLAN配置。4.2 SNMP类问题能用snmpget读到值但snmpwalk返回空。很可能是Community字符串权限不够只配了只读权限而且OID路径被精简了。在华为设备上需要额外配置snmp-agent protocol-source-interface或开启MIB视图。还有一种情况是交换机的MIB没有加载华为企业私有MIB库需要去华为官网下载对应版本的MIB文件导入到监控工具里。Trap收不到。检查三个地方一是交换机上的target-host配置地址是否写对了UDP 162端口是否能通到网关注意很多云服务器或防火墙默认不放行UDP 162端口二是网关的SNMP Trap服务是否在监听先用tcpdump抓包看看有没有UDP包进来没有的话问题在交换机侧三是确认Community字符串一致有些老设备发Trap用的Community和读数据的Community是分开配置的需要单独设置snmp-agent trap-community。设备温度、CPU等私有OID读取不到。华为不同型号设备的MIB库版本差异很大尤其是老款的S5700系列和新款的S5735系列OID完全不同。建议先在网上搜索自己设备型号的OID参考网或者直接在设备上执行display snmp-agent mib-view查看已加载的MIB。4.3 网关与整体系统问题网关重启后采集全部中断。很可能是采集程序没有注册成系统服务。Linux下用systemd把Python脚本设为常驻服务配置Restartalways掉线自动重启。这一步看似简单但在实际项目中非常重要——网关作为系统核心程序挂了等于整个监测系统瘫痪。数据库体积无限增长。每5秒一条记录一年大约630万条记录SQLite也能扛得住但文件会很大。建议定期做数据归档或者只保留90天的明细数据更早的数据转存CSV后归档再清空原表。温湿度数据的历史趋势分析价值远低于实时告警价值没必要长期保留高频率数据。多楼层IP地址冲突。项目部署中经常遇到同一个IP被规划到多个楼层的情况。务必要做一张详细的IP规划表分配给传感器、网关和交换机的IP逐一登记避免后期排查时楼上楼下设备互相冲突。我发现这比技术本身就重要得多一个清晰的IP登记表能让排查时间减少一半以上。5. Modbus TCP vs UDP 在温湿度监测场景的取舍我在项目中两种协议都实际用过分享一下选择建议。Modbus TCP的优势在于可靠有连接确认和重传机制数据不会丢。代价是每5秒建立一次连接、发送请求、读取响应、断开连接如果传感器数量多网关需要维护的连接数就多线程开销也大。我实测过50个传感器的场景5秒轮询间隔下网关CPU占用率能到20%左右虽然没到瓶颈但要注意优化。Modbus UDP就轻量多了无连接、无重传适合传感器主动上报或网关周期性广播读取。但UDP有个天然的坑请求丢了传感器不感知响应丢了网关不感知数据就静默丢失了。解决方法是加一层可靠性机制连续N次读到同一个值或超时判定为通信异常日志里做标记或者让传感器开启主动上报模式定时把数据怼到网关上网关只做接收这样丢包的影响更小。我现在的设计是重要机房和配电间的传感器用Modbus TCP一般的办公楼层、库房用Modbus UDP按区域的重要度选择协议既保证了关键区域的可靠性又控制了网关资源消耗。另外有个成本因素支持Modbus TCP的传感器比仅支持RTU的贵50%左右如果甲方预算紧张可以考虑混合方案核心区域用Modbus TCP传感器普通区域用RS485传感器接一个Modbus RTU转Modbus TCP网关由网关做协议转换。这样既能在上层统一走IP网络又平衡了成本。6. 运行效果与项目复盘系统上线运行几个月整体效果在意料之内。有时候机房空调故障温湿度传感器20分钟内就能发现温度异常联动逻辑会把交换机温度和传感器温度一起展示在告警页面运维一眼就看出问题在哪。而之前没有这个系统时往往要等到设备温度告警或者机房管理员巡检才发现等发现问题机房里的设备已经在高温下运行了几个小时了。实际的运维过程也验证了选型的合理性传感器故障更换时只需要把新传感器的IP改成和旧的一样或者改一下采集程序的IP配置不用改任何线路。因为每个传感器独立IP不再有485总线一拖一大串的问题单点故障对系统的影响降到了最低。要说什么地方还能优化一是传感器本身的数据精度低端传感器在湿度大于80%RH时误差会加大环境湿度高的时候数据仅供参考二是SNMP Trap的告警解析还需要加强华为设备不同的告警类型字段格式不一样需要做一个告警翻译映射表这部分我还在继续完善。最后分享一个我实际踩过的坑当初装传感器时为了美观把一个弱电间的传感器塞进了吊顶里结果那个弱电间恰好有空调风管经过吊顶内温度和实际空间温度差了3度以上一直没发现。后来因为一次温度告警排查才发现把传感器移到吊顶外的壁装位置后温度数据才正常。传感器的安装位置决定了数据的可信度这一点在实际项目中比选什么协议、用哪家设备都重要。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。