ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

带本地存储的POE温湿度记录仪:STM32+SNMP+审计报表设计

带本地存储的POE温湿度记录仪:STM32+SNMP+审计报表设计 前阵子给一个中型数据中心做环境监控改造甲方审计时提了一个让人头疼的要求机房每个机柜的温度湿度曲线必须能追溯至少半年而且要能随时导出报表。市面上大多数温湿度传感器都支持SNMP上报可一旦网络抖动、交换机重启云端或监控平台的数据就断了审计时根本解释不清那段空白。后来我干脆自己做了一台带本地存储的POE温湿度记录仪把历史数据留在设备内部再通过SNMP和Web两种方式把曲线和报表拿出来。这篇文章就把整个设计思路、关键代码和踩过的坑完整记录下来给正在做机房监控或嵌入式网络设备的朋友一个参考。1. 机房环境监控的真实痛点为什么既要联网采集又要本地存储1.1 审计场景里最怕的一句话当时网络卡了一下做机房运维的都知道温度湿度数据平时看起来很好测一个传感器接上网络、配置好SNMP监控平台就能画出实时的温度曲线。但真正到了年度审计、故障回溯的时候问题就全暴露出来了SNMP走的是UDP采集平台如果恰好在那几分钟里断连数据就永远丢了就算采集平台有重传机制传感器端没有缓存重传也拿不到老数据。审计人员看到曲线图中间有一条几小时的空白想让他相信那段时间温度其实是正常的基本等于空口无凭。所以这次项目里我把设计重心放在了数据必须落在设备本地这层上。无论上层平台怎么断连记录仪自己按照固定周期采样、存盘网络恢复之后再去补读。这个思路很像行车记录仪——摄像头loop写入SD卡出事之后拔卡就能还原现场。机房温湿度记录仪也一样本地存储才是审计追溯的最后一道保险。1.2 POE供电解决的不只是少一个电源适配器机房机柜里最拥挤的不是网线而是电源插排。每个传感器都要占一个220V插座再加上密密麻麻的电源适配器理线理到头大。POE供电在这时候的优势就非常明显了一根网线同时搞定数据传输和电源供应传感器本身不再需要独立的电源适配器直接从交换机或POE供电模块取电就行。但这台记录仪对POE的需求比普通IP摄像头更苛刻一点。摄像头断一次电最多是画面黑一阵温湿度记录仪如果因为供电不稳反复重启本地存储的数据文件很可能损坏之前的记录就全废了。所以设计上必须考虑POE的启动电流、分级协商和稳定供电策略我在第6章会单独展开讲。1.3 需求边界这个设备到底替谁干活把这台记录仪的使用场景拆开看主要有三类角色在依赖它机房运维人员日常用监控平台看实时温度湿度收到越界告警后快速定位是哪个机柜出问题。审计人员需要导出某个时间段的温湿度报表字段要包含时间戳、温度、湿度、告警事件格式最好是CSV或Excel能直接打开的。设备本身要在断网、断电、存储异常的情况下仍然尽可能保住数据至少保证重启之后历史数据不丢。这三类需求对应到技术实现上就是三个核心模块SNMP协议栈用于网络上报与告警、文件化本地存储用于数据持久化、Web页面和报表导出用于审计查询。后面章节就围绕这三块展开。2. 硬件方案选型主控、传感器、PoE模块与本地存储的组合2.1 主控为什么选STM32而不是高集成度的Linux小板最开始我也考虑过用树莓派Zero W或者类似的Linux开发板毕竟跑完整SNMP Agent、配一个SQLite数据库都很方便。但仔细掂量之后放弃了原因有三点第一是电源环境。Linux开发板对供电质量更敏感POE模块输出的一点点纹波都可能导致内核不稳定而在机房强电环境里这种干扰恰恰不好控制。STM32的电源域设计相对简单抗干扰能力在同等条件下更好调。第二是启动时间和异常恢复。Linux板子的文件系统如果突然断电容易损坏SD卡轻则需要fsck重则系统起不来。STM32配合裸机或RTOS上电几百毫秒就能进入工作状态没有复杂的文件系统挂载过程。第三是成本。机房里温湿度传感器一装就是几十个每个都上Linux板子单台成本会翻好几倍甲方预算也扛不住。STM32F407ZET6这颗芯片有足够的RAM和Flash跑lwIP协议栈还带硬件CRC和加密单元性价比高得多。最终的主控方案是STM32F407ZET6配合DP83848以太网PHY芯片、PoE PD模块和一颗SPI接口的NOR Flash。整个系统的资源分配是资源型号/容量用途主控STM32F407ZET6192KB RAM512KB Flash跑lwIP协议栈、SNMP Agent、存储管理网络PHYDP83848100M以太网物理层和PoE模块共用网口传感器SHT30I2C接口采集温度和湿度精度0.3℃/2%RH本地存储W25Q12816MB SPI NOR Flash存储历史温湿度记录和日志供电PoE PD模块IEEE 802.3af Class 2从网线取电输出5V给主控和传感器2.2 POE供电链路的两种落地方式POE供电的实现有两条路线我在设计时都试过一条是直接用标准的PoE分离器。这种分离器一头插网线一头输出5V/9V/12V电源和一个RJ45数据口设备端完全不需要知道POE的存在。优点是开发快成本低缺点是分离器本身作为一个外置模块故障点多一个而且在机柜里多了一个小盒子布线不够利落。另一条是把POE PD模块直接画到设备板子上。比如用TI的SI3402或者MP8007这类芯片把网线上的48V电压拉出来通过DC-DC转换成本地供电电压。这个方案的集成度更高但需要注意的是POE分级电阻的选择。IEEE 802.3af协议里分0到4级不同级别对应不同的最大功率同时交换机会根据分级结果决定是否给这个网口供电。选Class 2还是Class 3要提前计算整板功耗留出1.5倍余量否则强启的时候容易供不上电。我最终用的是板载PoE模块方案。实测下来整板功耗在2.8W左右因为带了一颗本地Flash和100M PHY所以选的是Class 3PSE端能供到6.49W余量比较健康。如果要挂外部设备直接把5V输出引到排针即可。2.3 传感器选型别只看精度参数温度湿度传感器看起来是整套系统里最简单的部分实际坑不少。选SHT30而不是更便宜的DHT11原因有几个DHT11的单总线协议对时序要求非常苛刻在RTOS环境下容易受任务调度影响偶尔会读到错误数据。SHT30是I2C接口支持CRC校验每个字节都能验一下数据完整性对于本地存储来说坏数据混进去会影响整个报表的可信度。SHT30的测量范围是-40℃到125℃湿度0到100%RH覆盖机房所有场景DHT11的高湿区精度太差机房空调除湿工况下测出来完全不准。还有一个容易被忽略的细节是传感器的刷新频率。SHT30本身支持每秒测量几次但记录仪不需要那么高频我设置的是每10秒读一次实时值每分钟把当前值落盘一次。采样周期太长曲线会丢失细小的波动太短Flash写入压力大而且温湿度本身是惯性量每分钟一个点已经足够反映机柜的温升趋势。2.4 本地存储介质NOR Flash、SD卡还是铁电RAM本地存储介质的选择直接影响使用寿命和数据安全性我梳理下三种方案的对比存储介质容量写入寿命掉电安全性成本SPI NOR Flash16MB约10万次擦除/扇区高单字节写入原子性强中SD卡数GB视Flash芯片而定垃圾回收逻辑不可控低突然断电易坏文件系统低FRAM铁电存储器几十KB到几MB几乎无限极高高我最终选了SPI NOR Flash容量16MB单条记录按照16字节设计每分钟一条一天86400秒除以60等于1440条再乘以16字节大约是23KB一天一年不到10MB。16MB的Flash哪怕是满打满算也足够存一年多的数据配合循环覆盖的策略完全满足审计半年的要求。SD卡的容量虽然大但文件系统的掉电保护是个老大难。裸写扇区不现实上FATFS的话一旦突然断电文件分配表很容易坏恢复起来费劲。NOR Flash配合自研的环形日志结构反而能控制在简单可靠的范围内。FRAM是个好东西但容量做不了这么大用来存系统配置和关键报警状态还差不多不适合做历史曲线的大容量存储。3. SNMP v2c代理与OID树设计让数据能被标准网管系统读到3.1 MIB文件先行先把OID设计清楚再写代码很多嵌入式开发者写SNMP Agent的时候习惯先把代码跑通再回头补MIB文件我觉得这个顺序反了。MIB文件不仅仅是给网管软件看的文档它本身就是SNMP Agent的数据字典。先把OID树设计清楚后面的代码实现、请求分发、数据结构的组织都会顺很多。我这台记录仪的MIB设计如下企业私有号段用1.3.6.1.4.1.xxxxx占位正式产品需要申请自己的企业号SNMPv2-SMI::enterprises.xxxxx |-- systemInfo (1) | |-- deviceName (1) // 设备名称字符串 | |-- firmwareVersion (2) // 固件版本 | |-- uptime (3) // 开机时间单位秒 |-- environment (2) | |-- temperatureCurrent (1) // 当前温度单位0.1℃ | |-- humidityCurrent (2) // 当前湿度单位0.1%RH | |-- temperatureMax (3) // 当日最高温度 | |-- temperatureMin (4) // 当日最低温度 | |-- humidityMax (5) | |-- humidityMin (6) | |-- alarmStatus (7) // 当前告警状态bitmap |-- history (3) | |-- historyTable (1) // 历史数据表 | | |-- historyEntry (1) | | |-- index (1) // 行序号 | | |-- timestamp (2) // Unix时间戳 | | |-- temperature (3) // 温度值 | | |-- humidity (4) // 湿度值 | | |-- eventFlag (5) // 事件标志上电/越界/恢复正常 |-- export (4) | |-- exportRequest (1) // 写1开始导出CSV | |-- exportStatus (2) // 导出状态0空闲 1生成中 2完成 | |-- exportResult (3) // 导出结果文件长度 | |-- exportData (4) // 分块读取导出数据OCTET STRING这个MIB设计的时候有一个关键考虑历史数据表必须支持GETNEXT和GETBULK操作。如果只支持GET精确读取网管系统要拿到一年的曲线数据就得一个OID一个OID地遍历效率极低。通过把历史数据设计成表格结构并实现GETNEXT外部系统可以用GETBULK请求一次拉回大量记录速度快得多。3.2 lwIP自带SNMP代理的取舍与改造STM32上最常用的网络协议栈是lwIP它自带了一个轻量级的SNMP Agent实现支持SNMP v1和v2c的GET、SET、GETNEXT、GETBULK这些基本操作。但lwIP自带的Agent有个局限它的MIB对象是用宏定义静态注册的数据访问的逻辑和lwIP内部模块耦合在一起。如果只是上报几个系统状态变量还好要做一张有几千行数据的历史表直接改lwIP源码里的mib2.c会改到怀疑人生。我的做法是保留lwIP的UDP协议栈SNMP Agent的编解码部分自己实现。SNMP v2c的核心格式并不复杂BER编码Basic Encoding Rules跑一遍PDU的类型就那么几种对于温湿度记录仪这种小数据量的设备手写编码器反而灵活。关键数据结构就两个一个负责把SNMP请求的OID解析成内部的对象定位符一个负责把内部的数据组装成SNMP响应报文。后面第4章我会把GETBULK处理历史表的核心逻辑画一下。3.3 Trap告警断电、越界、存储异常都要上报SNMP Trap是一条主动上报的通道设备一旦发现问题不等监控平台来轮询直接发UDP包到配置好的Trap接收端。温湿度记录仪里我设置了四类TrapTrap类型触发条件严重程度coldStart设备上电初始化完成通知temperatureAlarm温度超过设定上限或低于下限严重storageErrorFlash写入失败或校验错误严重memoryAlmostFull剩余存储空间不足10%警告Trap发送用的是SNMP v2c的Inform格式比v1的Trap-PDU多了一个请求ID接收端收到之后理论上要回一个Response包确认。不过在嵌入式设备上UDP本身不可靠我们一般只负责把Inform包发出去收不到确认就重发三次不做更复杂的可靠传输。真要保证告警不丢得靠Zabbix这类平台的告警确认机制去兜底。Trap配置放到设备Web页面里可以设置最多两个接收端IP和端口号。这个功能看着不起眼实际使用的时候特别重要因为机房环境比较恶劣有时候某个机柜突然升温平台轮询周期是5分钟等发现问题已经晚了Trap可以在秒级把这个信息推给值班人员。3.4 编码示例SNMP GET返回温湿度数据的处理路径下面这段代码展示SNMP Agent收到一个GET请求后从OID解析到返回数据的基本处理流程。这里用简化的伪代码描述实际项目中按这个逻辑展开即可// SNMP PDU解析入口 void snmp_agent_process(uint8_t *buf, uint16_t len) { snmp_message_t msg; ber_decode_pdu(buf, len, msg); // 1. BER解码取出PDU类型和OID列表 if (msg.pdu_type SNMP_GET) { for (int i 0; i msg.oid_count; i) { oid_entry_t *entry msg.oids[i]; snmp_varbind_t result; // 2. 根据OID前缀判断走哪个模块 if (oid_match(entry, PATH_ENV_TEMP_CURRENT)) { result.type INTEGER; result.value.int_val sensor_get_temperature(); } else if (oid_match(entry, PATH_ENV_HUMI_CURRENT)) { result.type INTEGER; result.value.int_val sensor_get_humidity(); } else if (oid_match(entry, PATH_SYS_UPTIME)) { result.type TIMETICKS; result.value.int_val system_get_uptime_ms() / 10; } else { // 3. 找不到OID则返回NO_SUCH_NAME result.type SNMP_NOSUCHNAME; } snmp_add_varbind_to_response(msg, entry, result); } } // 4. 编码响应包并通过UDP发送 uint8_t outbuf[1500]; uint16_t outlen ber_encode_pdu(outbuf, msg, SNMP_GET_RESPONSE); udp_sendto(snmp_pcb, outbuf, outlen, msg.src_ip, msg.src_port); }这里有三个容易出问题的地方OID匹配不能用字符串比较要按子标识符逐级拆开比对否则性能会很差。温湿度数值用整数表示单位是0.1℃和0.1%RH。SNMP的INTEGER没有浮点类型要么用INTEGER带小数位要么用OCTET STRING存字符串我优先用整数因为Zabbix里做触发器表达式更直观。响应包长度必须严格限制在UDP payload里超过1500字节的包会被分片很多监控平台的SNMP模块对分片包处理不好宁可分多次返回。4. 历史曲线查询从SNMP批量读到WEB页面的完整链路4.1 GETBULK批量读数据的OID组织技巧历史曲线的数据来源是本地Flash里存的那张循环表。外部系统通过SNMP访问这张表的时候最核心的操作就是GETBULK批量读取。GETBULK的工作方式是一次请求带上一个起点OID和一个最大返回条目数Agent会从起点OID开始自动往后遍历若干条记录。实际操作中有一个技巧GETBULK的max-repetitions参数不能设置太大否则一次要返回几十KB数据UDP包会被分片。我一般控制在100条记录以内。假设历史表每条记录16字节SNMP响应包头占用60字节左右100条记录大概1600字节加上编码开销会超过MTU所以实际设置50~80条比较稳。如果监控平台想要获取某一天的数据它只需要把起点OID设置成这一天的0点0分对应的表格行位置然后反复GETBULK直到拿到当日最后一行的数据。这里的行位置和时间的关系由Agent内部维护外部系统不需要知道行号直接遍历即可。4.2 设备内置Web页面的历史曲线实现即便有了SNMP运维人员还是需要一个更直观的看图入口。监控平台画出的历史曲线通常是以天或周为单位的聚合想要看具体某个机柜某一次波动的原始细节还是直接打开设备内置的Web页面最方便。Web页面基于lwIP自带的HTTP服务器改造前端只用了最简单的Canvas画图没有引第三方图表库。页面结构很简单首页显示当前温度、湿度、设备状态和最近一个小时的曲线。历史查询页面可以选起始时间和结束时间查询结果以折线图展示。导出页面提供两个按钮一个是导出CSV文件一个是导出PDF报表PDF报告这块嵌入式设备上做重页面容易卡简单场景用CSV足够了PDF方案是在上位机完成后面再讲。Web页面的历史曲线请求本质上是向设备发一个HTTP GET请求带start_timestamp和end_timestamp参数设备在本地Flash里检索对应的数据段按JSON格式返回。前端拿到JSON数组后渲染Canvas。由于一年十万多个点全部画在Canvas里会导致浏览器卡死所以Web页面只展示采样间隔在5分钟以上的聚合曲线要看原始明细就下载CSV。4.3 时间戳精度与查询窗口划分历史查询最关键的是时间对齐。嵌入式设备没有RTC电池备份的话断电重启后时间会回到编译固件的默认时间历史数据的时间戳就会错乱。所以我的设计里加入了一个辅助机制设备正常运行时通过NTP协议和局域网时间服务器同步时钟每小时校准一次。如果设备曾经断电RTC使用后备电池维持计时NTP恢复后重新校准。每条历史记录的timestamp字段都存Unix时间戳所有查询和报表导出都基于这个绝对时间值不依赖设备当前的系统时间。这个设计在审计追溯时非常重要。审计人员要求的是某个真实时刻的温湿度数据而不是设备运行了多久之后的第N个采样点时间戳必须可靠可验证。如果设备时间发生过跳变导出的报表里也要能看出来所以事件标志字段里专门有一个timeAdjust标志位记录时间被NTP校准的时刻。5. 审计报表导出的两条路线直出CSV与接入现有监控平台5.1 设备直出CSV报表的字段设计审计报表最刚性的需求是CSV因为它能被Excel直接打开、可以筛选、可以做透视。导出的字段我经过和甲方审计人员几轮沟通最终定成下面这个格式字段示例值说明timestamp2024-06-15 14:30:00本地时间格式固定为YYYY-MM-DD HH:MM:SStemperature23.4数值单位℃humidity45.2数值单位%RHevent_flag00正常 1上电 2温度越界 3湿度越界 4恢复 5时间校准device_namerack-A12设备名称方便多台设备数据合并时区分来源字段定这么细是有原因的。机房审计不能只看温度湿度两头还要看是否有过停电、是否有过告警、是否发生过时间跳变。event_flag把关键事件融进同一条数据流里审计人员筛一下event_flag ! 0的行就能快速找到所有异常节点。导出CSV的方式有两种一种是通过Web页面的导出按钮直接下载另一种是通过SNMP的export模块触发设备在本地生成CSV文件然后外部系统用FTP或HTTP的方式把文件拉走。如果只是偶尔导一次Web页面下载就够了如果要做每周例行审计归档建议用后一种自动化方案脚本定时触发导出并归档到审计服务器。5.2 通过SNMP拉取数据喂给现有监控平台很多机房在用的监控平台是Zabbix它天生支持SNMP协议但默认的模板对私有MIB支持得不好。要让Zabbix直接读取这台设备的温湿度数据需要把MIB文件编译进Zabbix模板创建对应的监控项和图形。如果是历史报表需求更通用的做法是用Python脚本通过SNMP把设备数据拉出来写入InfluxDB并用Grafana做可视化。下面这个简化的脚本演示了用pysnmp读取历史表的逻辑from pysnmp.hlapi import * def get_history(host, start_oid, max_records100): results [] error_indication, error_status, error_index, var_binds next( get_bulk_cmd( SnmpEngine(), CommunityData(public, mpModel1), UdpTransportTarget((host, 161), timeout2, retries2), ContextData(), 0, # non-repeaters max_records, # max-repetitions ObjectType(ObjectIdentity(start_oid)), lookupMibFalse ) ) for oid, value in var_binds: results.append((str(oid), str(value))) return resultspysnmp的GETBULK返回顺序是按OID字典序排列的所以外部脚本直接循环将返回的OID和时间戳字段映射即可。对于审计报表我建议在拉取完成后把数据转存到PostgreSQL或MySQL里方便之后按时间窗口做二次聚合。5.3 报表合并与机房审计周期单台设备导出的CSV是孤立的审计通常需要把整层机房或整个数据中心的所有记录仪数据合并成一张总表。这一步我建议做个简单的ETL流程每台设备一个固定IP脚本按设备清单逐个拉取CSV合并成一个按照时间戳排序的大表。合并的时候有几个注意事项所有设备的时钟必须先对齐NTP服务器用同一个。报表文件名带上设备序列号和日期范围防止同名文件互相覆盖。如果在审计周期内有设备掉线几个小时掉线期间的数据在报表里不能凭空消失要么留空行要么在备注列里标注设备离线无记录。诚实的缺测标注比用插值补出来的假数据更符合审计要求。之前遇到过一个甲方的审计人员要求报表必须能追溯到每一次空调启动和停机对机柜温度的影响。这种分析光靠温湿度数据还不够还需要空调的功耗数据。所以我又在设备上加了一路485接口接空调的RS485通讯线把空调的运行状态和设定温度也一并记录到本地Flash里。这样导出的报表就能同时看到空调动作和温度波动的关系审计说服力直接上一个档次。6. 实测踩坑记录PoE启动电流、SNMP超时与Flash磨损6.1 PoE分级与启动瞬间的电压跌落第一次板子打样回来后上电测试就出了问题记录仪插到POE交换机上设备指示灯闪了一下就灭了反复试了几次都这样。用示波器抓POE模块的输出电压发现每次上电会有一个将近200ms的电压跌落直接从5V掉到3V以下STM32早就复位了。这个问题的根源太典型了POE分级电阻选得偏小PSE上电阶段按Class 2的功率上限供电5V输出的驱动能力不足以同时扛过主控启动、Flash初始化和以太网PHY的link-up过程。PHY的link-up瞬间会有一个瞬间电流尖峰整板功耗瞬时冲到5W以上超出Class 2的6.49W上限其实不远了但POE供电链路本身的纹波和压降把余量吃掉了。解决办法有两个方向第一个是改分级电阻到Class 3让PSE承诺更大的功率上限第二个是加缓启动电路在5V输出上串联一个小一点的电感或者用电子开关限流避免PHY和主控同一个瞬间同时满负荷。我两个都做了效果非常明显之后再没复现过启动掉电的问题。这里提醒一下POE交换机的供电能力不是无限的如果整柜设备都是Class 3还要核算交换机的总PoE功率预算。一台24口的POE交换机按30W每口算不是所有口都能满载的实际部署时要把设备的实际功耗列个表避免过载。6.2 SNMP请求超时与重试策略SNMP协议本身是基于UDP的请求超时后重复是家常便饭。但不同监控平台的超时设置差异很大Zabbix默认的超时是3秒如果设备响应慢一点就会被标记为不可达。实测发现设备在Flash擦除期间处理SNMP请求时响应延迟会从几毫秒飙升到几百毫秒因为Flash擦除操作会阻塞主控的总线访问。为了解决这个问题我把Flash擦除操作从主循环里拆出去放到一个低优先级的后台任务里执行每次擦除一个扇区就让出CPU。同时SNMP Agent模块里的数据读取全部走缓存实时温度湿度变量是每次采集后直接更新到内存中的SNMP请求查询的时候不需要访问Flash只从内存里取响应速度就稳定了。如果按照这个思路设计建议在设备文档里明确标注SNMP读操作超时建议设置为5秒重试次数建议2次。超时设太短会频繁误报设备离线设太长又会影响平台对告警的响应速度。5秒是一个比较平衡的值。6.3 Flash存储寿命估算与磨损均衡16MB的NOR Flash按每分钟一条记录一年也才写不到10MB数据看起来毫无压力。但这里要算一笔更细的账NOR Flash是按扇区擦除的W25Q128每个扇区4KB每次擦除的寿命是10万次左右。如果不做磨损均衡一直往同一个扇区写那这个扇区很快就会被写穿。我的环形存储实现是整个Flash分区划分为N个扇区维护一个写指针和一个擦除指针写满一个扇区就顺移到下一个待写入扇区如果之前有数据先擦除再写。通过这种循环写入的方式16MB的Flash拆成4096个4KB扇区理论上可以保证每个扇区的擦写次数相对均匀。按每天1440条记录、每条16字节计算每分钟数据量23KB大概每秒写完一个4KB扇区需要3.5分钟一年下来累计擦写次数是365天×1440分钟/每扇区可写4KB/16B256条≈2053次距离10万次的寿命上限还远得很。即便这样我还是在存储模块里加了一个坏扇区跳过机制。如果在写入过程中发现某次擦除或写入失败设备会把这个扇区标记为异常自动迁移到下一个扇区并上报一条storageError Trap。这个机制在项目部署后期很管用因为机房环境温度高Flash在高温下的数据保持能力会下降提前发现问题总比审计的时候拿不出数据强。6.4 部署细节探头位置比什么都重要最后一个坑不是电子的是物理部署的。有次现场调试一台记录仪装在机柜顶部温度曲线在白天经常出现异常尖峰查来查去发现是探头正好对着空调出风口空调启动瞬间温度被吹低了三四度不是真实的环境温度。正确做法是传感器探头装在机柜前门或后门的回风口位置远离空调出风直吹同时避开服务器风扇排风的强对流区域。在机柜上下三层各装一台设备是更专业的方案因为机房里的温度分层现象严重只测一个点位很容易出现顶部28℃、底部22℃这种偏差审计报表里如果只有单点数据说服力会大打折扣。另外传感器探头不要贴在金属机柜表面。机柜的铁皮是热的良导体贴上去会测得比实际环境温度偏高。用双面泡棉胶垫高1厘米左右让探头悬空测出来的才是真正的空气温度。这些小细节看似不起眼在审计的时候往往就是决定报表能不能过关的关键。写在最后的一点经验这项目做完之后的感受是温湿度记录仪这种东西单看每个功能点SNMP、POE、Flash存储、CSV导出都不是什么新技术但把它们组合在一起再加一个审计级可靠性的要求难度就上来了。尤其是本地存储和SNMP的结合既要在嵌入式资源里跑通协议栈又要保证数据落盘的完整性和可追溯性这两个需求本身是有冲突的。我的建议是如果你也在做类似设备先把审计需求问清楚到底要保留多久的数据、允许多大的缺测率、报表要包含什么字段这些确定之后再定硬件方案和存储架构不然等设备量产了才发现存储容量不够或者导出格式不对改动成本会非常高。如果后续有时间我打算给设备加一个基于Web的远程固件升级功能这样部署在几十个机柜里的设备就不用一个个捅串口线升级了。固件升级过程中对历史数据的分区保护也要设计好毕竟设备可以重启几百次历史数据却不能丢一次。
返回列表