简介:面向环境监测与化工园区安全监管场景的无线传感器网络(WSN)案例分析文档,适合物联网、环境工程及安全生产管理方向的学习者与工程人员参考。内容围绕 RAE systems 气体传感器与 WSN 的结合,梳理监测终端、中继站、监控软件三部分构成的系统方案,并展开 Ad-hoc 自组网、JRc1 无线调制解调器、GPS 定位及 3—5 公里覆盖中继等关键技术点,同时说明突发泄漏事故的快速认定、应急响应与事后分析价值。资源包共 1 个 doc 文件,大小约 15KB,篇幅精炼,便于快速浏览整体框架与核心模块。已有 849 人学习下载,可作为理解 WSN 环境监测应用、整理方案思路和课堂案例的轻量参考资料。
1. 一份 WSN 环境监测案例文档:先看数字,再看结论
化工园区的环境监测方案评审,最怕技术讲得很满、落地参数一个都对不上。翻这份 WSN 无线传感器网络应用案例文档时,我的第一反应是它不像宣传材料:终端挂几路传感器、中继覆盖多大半径、软件里装多少种物质、数据从哪个环节进模型,全都有具体数字可以拿去核对。它描述的是某化工园区的一套实时环境监测系统,用无线方式把气体浓度和位置信息送到监控中心,支撑事故前的预警、事故中的危险区快速判定、事故后的取证分析。适合三类人:做园区监测选型的集成商、要写技术方案的负责人、刚接触 Ad-hoc 组网想找完整参照的工程师。文档不厚,但每一节都能对应一个可执行动作,这才是它值得逐页拆开的原因。
2. 三层链路的落地分工:终端、中继、监控中心各自该背什么指标
这套系统的骨架只有三段:监测终端采数据、智能中基站转发数据、监控中心算数据。听起来平平无奇,真正决定项目成败的是每一段背了哪些量化指标,以及指标之间是否自洽。终端多挂一路传感器,电池组就要重算;中继半径写大 1 公里,遮挡场景下就可能整片盲区;软件物质库填得再全,物质标识对不上现场实际泄漏物,扩散模型输出的等值线就是一张好看的废图。下面按数据流向把三段拆开,每一段都给可核对的计算方式和参数表。
2.1 监测终端:1 到 5 路传感器、GPS 与电池组怎么配
案例文档给终端的配置是 1 到 5 路传感器、一个 JRc1 无线模块、GPS 和电池组。这个「1 到 5」不是随手写的上限,它背后有四条硬约束:机箱内部空间与走线、供电总线的电流余量、多路气体之间的交叉干扰标定工作量、以及单帧数据长度对空口占用的影响。实际项目里我一般按「先定气体种类,再定量程,最后定路数」的顺序推进——先确认园区里需要盯的是硫化氢、一氧化碳、可燃气体还是挥发性有机物,再按职业接触限值和传感器量程留 2 到 3 倍余量,最后才决定一个终端装几路。路数越多,单点成本越低,但标定和维护的工作量是线性涨的,这一点在验收后第三年会被放大得特别明显。
终端侧最容易被忽略的是功耗预算。传感器、无线模块、GPS、主控四类器件的电流量级差得很远,必须按占空比折算成日均耗电,再反推电池组容量。下面这张表是量级参考,实际填的时候要换成器件手册里的数字:
| 部件 | 工作电流(量级) | 典型占空比 | 日均耗电折算 |
|---|---|---|---|
| 气体传感器 | 15 到 25 mA | 连续工作 | 约 360 到 600 mAh |
| 无线模块(接收) | 25 到 40 mA | 约 10% | 约 60 到 95 mAh |
| 无线模块(发射) | 200 到 300 mA | 约 2% | 约 95 到 145 mAh |
| GPS 模块 | 30 到 40 mA | 约 15%(定位后降频) | 约 110 到 145 mAh |
| 主控与采集 | 5 到 10 mA | 连续或低频唤醒 | 约 120 到 240 mAh |
把日均耗电算出来之后,电池容量按三步走:第一步乘自持天数,第二步除以蓄电池允许放电深度,第三步再除以低温与老化折减系数。举个具体算例,日均耗电折合约 1 Ah、电压 7.4 V,要求阴雨天自持 3 天,放电深度取 0.6、低温与老化折减取 0.8,则所需容量约为 1 × 3 ÷ 0.6 ÷ 0.8 ≈ 6.25 Ah,选 7.4 V/8 Ah 的组才踏实。很多人第一次算会把放电深度当成 1,结果现场跑不到标称天数的一半,这类翻车在北方冬季尤其集中。
GPS 在这里的定位不是「厘米级定位」,而是给每条数据打一个空间标签。化工园区的钢结构罐区、管廊、装卸台会让民用定位漂出几十米,所以工程上常见的做法是双轨制:设备安装时把点位编号写进配置,数据帧里同时带点位编号和 GPS 坐标,模型和报表以点位编号为主键,GPS 只用于移动式终端和事后轨迹校核。这个约定看起来不起眼,但它决定了事后回溯时你能不能把一条超标记录准确落到具体罐区。
2.2 智能中基站:3 到 5 公里覆盖半径背后的四个变量
文档里写中基站能覆盖 3 到 5 公里半径,并且集成无线模块和太阳能供电,不需要数据电缆和电源线。这个数字要拆成链路预算来看,不能直接抄进方案里当承诺值。自由空间路径损耗的常用估算式是 Lp = 32.44 + 20lg(f) + 20lg(d),f 取 MHz、d 取 km。以 470 MHz 频段、5 公里距离代入,Lp 约为 100 dB;发射功率 30 dBm、两端天线各 2 dBi,接收电平约 -66 dBm,而典型工业无线模块的接收灵敏度在 -105 到 -110 dBm 之间,视距条件下余量四十多 dB,确实很宽裕。
问题出在「视距」两个字上。园区里高塔、球罐、管廊、厂房会吃掉大量余量,常见做法是按场景给折减系数:开阔地带取 0.8 到 0.9,一般装置区取 0.5 到 0.6,密集罐区与多层管廊取 0.35 到 0.45。也就是说标称 5 公里的设备,进罐区后等效半径可能只剩 2 公里出头。我在评审时见过把 5 公里直接画在平面图上、结果罐区背面一片盲区的方案,返工成本远高于前期多布两个中继。折减系数没有标准答案,稳妥的路子是先按 0.5 做初步布点,再用现场实测的接收电平和丢包率回头修正。
太阳能供电这部分同样要算账,而且比终端更容易出错,因为中继是 7×24 小时常开的。计算顺序是:先算日均耗电(发射功率、路由计算、夜间值守都算进去),再乘连续阴雨备电天数,除以蓄电池放电深度和系统效率,得到电池容量;太阳能板功率则按日均耗电除以当地峰值日照小时数、再除以系统效率,最后乘一个 1.2 到 1.4 的补充系数。举个算例:日均耗电 120 Wh,要求阴雨自持 3 天,放电深度 0.6、系统效率 0.85,电池容量约需 705 Wh,折合 12 V/60 Ah;峰值日照按 3.5 小时、效率 0.75 算,板子至少要 46 W,实际选 60 W 以上才够覆盖冬季衰减。
还有两个参数经常被漏掉。一是低电压告警必须回传,中继掉电前要能把「我快没电了」这件事送到监控中心,否则运维只能靠人巡。二是蓄电池的低温特性,标称容量是在 25 摄氏度下测的,零下十度能放出来的电量可能只有六七成,这一条在北方项目里要单独留余量。
2.3 监控中心:物质库、扩散模型和协议适配层的关系
监控中心这一层,文档强调的是「复杂数学计算法则与天气、地点、事故性质、危化源性质、扩散或泄漏情况、地形学结合」,以及一个含 700 种以上化学物质的数据库和情景再现程序,输出报告、图表、等值线图和重要点图。把它翻译成工程语言,中心侧其实是四条流水线:接入与协议适配、时序存储、模型引擎、呈现与导出。
接入层要做的事比想象中多。终端上报的是通道号、原始码值、状态位、点位编号、时间戳,中心侧要先把码值按量程和标定系数换算成浓度,再映射成业务语义,然后入库。我一般会把这一层单独做成可配置的映射表,而不是写死在采集程序里,因为传感器换型、量程调整、通道增删在项目生命周期里太常见了,写死一次就要改一次代码。映射表至少要包含四列:设备序列号、通道号、物质标识、量程与单位。
物质库是这一层最容易被低估的部分。700 种物质意味着库里有机动范围,但也意味着现场必须做一次逐项核对:园区实际存在的物质,在库里对应哪一条,分子量、蒸气压、密度、毒性阈值这些模型参数是否齐全。同分异构体、混合物、商品名和化学名不一致,是导致模型算错范围的三大主因。常见做法是建一张现场物质映射表,左边写工艺台账里的物质名称,中间写库内条目编号,右边写对应的传感器通道,三者对不上的必须在上线前解决。
模型引擎侧的输入字段决定了输出可信度。气象数据(风向、风速、大气稳定度)、地形(平坦、丘陵、建筑群遮挡)、源强(泄漏速率、持续时间、相态)、泄漏形态(瞬时释放还是连续泄漏、液池蒸发还是喷射)这几类字段,缺一项就要在报告里明确标注降级,不能让用户以为等值线是精确结果。这一点在事后取证时尤其关键,报告里写清假设条件,比给出一个漂亮但无法解释的数字更有价值。
3. Ad-hoc 组网在遮挡园区怎么跑通:自组网、路由收敛与布点几何
文档对 Ad-hoc 的描述集中在三点:节点之间可直接通信、不需要固定网络平台、拓扑变化时自动组网自动找路由自动重建。这三句话对应的是三个工程问题:为什么园区不能拉有线、多跳之后性能衰减到什么程度、以及布点怎么用几何方法算而不是拍脑袋。很多人把 Ad-hoc 当成「装上就能自己通」的玄学,实际上它的表现高度依赖节点密度、跳数上限和业务帧的优先级设计,调不好就会出现「网是通的、告警是慢的」这种最难排查的状态。
3.1 为什么园区场景用不了星型点对点
星型结构的隐含前提是所有节点都能直接看见中心。化工园区恰好违反这个前提:球罐、高塔、管廊、厂房构成大量非视距路径,单点直连要么靠抬高天线,要么靠加大发射功率,两条路都有天花板。抬天线受限于现场结构审批和防雷,加功率受限于设备合规和功耗。更麻烦的是单点故障——中心侧一个接收机出问题,整片区域的数据全断。
Ad-hoc 的价值在这里体现:每个节点既是终端也是转发者,数据可以绕开遮挡,多跳到达中继或中心;某个节点掉线,路由能重新找一条路径,不至于整片瘫痪。代价是复杂的调度和更多的状态维护,网络规模越大、跳数越多,端到端时延和丢包就越难保证。所以我一般会把 Ad-hoc 用在「布点密集、单跳不可达、但业务允许秒级时延」的场景,要求毫秒级联锁的动作绝不放在这条链路上。
还有一个经常被忽略的收益:供电与施工成本。中基站不需要数据电缆和电源线,意味着布点位置由覆盖需求决定,而不是由「哪里有电、哪里能挖沟」决定。这一条在已投产的园区里价值很高,因为动土和动电的审批周期往往比设备采购还长。
3.2 入网、收敛、重路由:现场该盯的五个指标
Ad-hoc 网络的调试不能只看「通没通」,要盯住一组可量化的运行指标。下面这张表是我在联调阶段必看的五项,每一项都要有明确的合格线,否则验收时说不清楚:
| 指标 | 观察方式 | 参考合格线 | 不达标时的第一动作 |
|---|---|---|---|
| 入网时间 | 上电到首次上报的间隔 | 小于 3 分钟 | 检查节点密度与初始信道配置 |
| 平均跳数 | 路由表统计 | 不超过 3 跳 | 增设中继,压缩单跳距离 |
| 端到端丢包率 | 定时心跳包统计 | 24 小时低于 1% | 看链路质量余量,排查干扰源 |
| 重路由频次 | 单位时间内路由变更次数 | 每小时不超过 2 次 | 排查链路抖动与供电不稳 |
| 端到端时延 | 带时间戳的探测帧 | 95 分位小于 2 秒 | 限制最大跳数,给告警帧提优先级 |
现场验证的步骤我一般这么走:先在实验室把全部节点摆在一间屋里,确认入网、路由和心跳正常;再拉到现场按设计点位安装,逐点记录接收电平和跳数;然后人为拔掉一个中间节点,观察重路由时间和数据补传情况;最后做一次连续 24 小时的静置观测,看丢包和重路由频次是否稳定。这套流程走完,网络的脾气基本就摸清了。
「重路由频次」是最容易被忽略的一项。链路在临界状态反复抖动时,网络看起来一直在线,但每次重路由都会带来一段缓存丢弃,表现出来就是告警偶尔迟到几十秒。这种问题不会在验收测试里暴露,只会在真实泄漏时暴露,代价很大。
3.3 布点几何:用覆盖校核脚本把 3 到 5 公里变成落点表
覆盖半径是圆的,园区是方的,中间还夹着遮挡。手工在平面图上画圈很容易画出自欺欺人的结果,我习惯先用一个小脚本做网格化覆盖校核,把候选点位、折减后的等效半径和园区边界喂进去,输出覆盖率数字和盲区位置,再拿这个结果去和现场实测对照。下面这段是可直接改参数用的版本:
# 覆盖校核:输入候选点位与折减后的等效半径,输出网格覆盖率 import math # 园区边界,按局部坐标系平移,单位米 X_MIN, X_MAX = 0, 3000 Y_MIN, Y_MAX = 0, 2000 GRID = 25 # 网格边长,25 米足够看清盲区分布 # 候选点位:(x, y, 标称半径, 遮挡折减系数) # 折减系数:开阔 0.8~0.9,一般装置区 0.5~0.6,密集罐区 0.35~0.45 CANDIDATES = [ (400, 500, 5000, 0.55), (1500, 1200, 5000, 0.45), (2500, 800, 5000, 0.60), ] def coverage_ratio(nodes, grid=GRID): total = hit = 0 for x in range(X_MIN, X_MAX, grid): for y in range(Y_MIN, Y_MAX, grid): total += 1 for nx, ny, r, k in nodes: # 用等效半径判断是否覆盖,k 越小代表遮挡越重 if math.hypot(x - nx, y - ny) <= r * k: hit += 1 break return hit / total if __name__ == "__main__": print(f"覆盖率:{coverage_ratio(CANDIDATES):.1%}") # 逐点去掉一个中继,看覆盖率掉多少,评估单点故障影响 for i in range(len(CANDIDATES)): rest = CANDIDATES[:i] + CANDIDATES[i + 1:] print(f"去掉点位 {i} 后覆盖率:{coverage_ratio(rest):.1%}")这段代码的逻辑很直白:把园区切成 25 米见方的网格,每个网格中心点只要落在任一节点的等效覆盖圆内就算被覆盖,最后统计比例。三个参数要按实际情况改:GRID决定分辨率,25 米对园区级规划够用,缩到 5 米计算量会涨二十多倍;折减系数k是最关键的经验值,宁可先取小再上调,也不要取大后自我安慰;候选点位来自现场踏勘,必须包含可立杆、可取电或可装太阳能板的位置,图上画得再漂亮、现场没地方装也是白算。
脚本最有价值的输出不是那个百分比,而是「去掉一个点位后覆盖率掉多少」。掉得超过 15% 的点位就是网络里的关键节点,必须配双份或者预留备用路由。我一般会把这个敏感性分析直接放进方案附件,评审时比一张漂亮的覆盖图有说服力得多。
4. 从读数到扩散预测:监控软件的输入字段、告警分级与取证链
监控软件是这套系统里最容易被当成黑匣子的部分。文档说它能结合天气、地点、事故性质、危化源性质、扩散或泄漏情况、地形学预测影响范围,还能输出报告、图表、等值线图和事故总体影响分析。这些能力要真正可用,前提是三件事做到位:输入字段有明确的来源和缺省策略、告警判定有可解释的规则、原始数据和时间戳能被完整留存。缺任何一件,软件输出的结论在事后都很难站得住。
4.1 四类输入字段:气象、地形、源强、泄漏形态
模型吃进去的东西决定了吐出来的东西。按类别拆,输入字段大致是四组,每一组都要写清来源、单位、取值范围和缺失时的降级策略。下面这张表可以直接拿去当需求清单用:
| 类别 | 关键字段 | 单位与范围 | 缺失时的处理 |
|---|---|---|---|
| 气象 | 风向、风速、大气稳定度、温度、湿度 | 度、m/s、等级、摄氏度、% | 就近取园区气象站,标注数据来源与时差 |
| 地形 | 地面粗糙度、建筑与罐体遮挡、坡度 | 分类值、米 | 按最不利类别代入,报告注明假设 |
| 源强 | 泄漏速率、持续时间、物质相态、温度压力 | kg/s、分钟、气/液 | 按量程上限做保守估算并高亮提示 |
| 泄漏形态 | 瞬时释放 / 连续泄漏、液池蒸发 / 喷射 | 枚举 | 默认连续泄漏,直至人工确认 |
气象数据的坑最深。园区自建气象站往往装在办公楼顶,测出来的风向和罐区近地面风向能差几十度,而扩散方向对风向极其敏感。稳妥的做法是至少有一个测点靠近主要风险源,并且把测点位置写进报告附录。风速低于 1 m/s 的静风条件也要单独处理,很多模型在静风下会给出各向同性的圆形扩散,实际现场更接近不规则堆积,报告里要提示这一局限。
源强字段是最容易拍脑袋的地方。现场往往拿不到精确泄漏速率,工程上的折中是按设备口径、压力和物质状态做分级估算,给出「保守值」和「典型值」两档,模型跑两遍,报告里两套结果并列。这比给一个看似精确的数字负责任得多。
4.2 告警分级与数据清洗:把漂移和毛刺挡在阈值之外
告警判定不能只写一个阈值。传感器上电有预热期、长期运行有零点漂移、现场有瞬时干扰,这些都会制造无效告警。我的习惯是把通道级配置抽成独立文件,阈值、确认时间、复位时间、漂移上限都写成参数,改阈值不需要改代码:
# 通道级告警配置:按物质和量程分别设,不要全园区共用一套 channels: ch1_h2s: substance: "硫化氢" unit: "ppm" range: [0, 100] warm_up_s: 120 # 上电预热,期间读数不参与判定 baseline_drift_ppm: 0.5 # 24 小时零点漂移上限,超限触发维护工单 levels: warning: 5 # 预警:进入关注 alarm: 10 # 报警:启动应急流程 high: 20 # 高报:联锁与疏散建议 confirm_s: 30 # 连续超限 30 秒才置位,滤掉毛刺 recover_s: 60 # 回落到阈值以下 60 秒才复位,避免来回刷屏参数的含义要讲清楚:warm_up_s是电化学传感器上电后的稳定时间,不设这一项,每次重启都会来一波假报警;baseline_drift_ppm是健康度指标,它不直接产生告警,但会生成维护工单,这是把「传感器坏了才发现」变成「传感器要坏了就知道」的关键;confirm_s和recover_s是一对防抖参数,前者防瞬时毛刺,后者防阈值附近反复跳变把值班人员搞麻木。两个值设得太大会漏掉真实短时泄漏,我一般按传感器响应时间的 1 到 2 倍来定。
数据清洗还有两个动作:温湿度补偿和突变过滤。电化学传感器的输出随温度漂移是常态,补偿系数要么来自厂家标定曲线,要么用现场静置数据拟合,二者都要留档。突变过滤要谨慎,简单的滑动平均会把真实泄漏的上升沿磨平,常见做法是对上升沿用短窗口、对下降沿用长窗口,保证响应快、复位稳。
4.3 情景再现与事后取证:时间戳、原始包、空间标签三件套
文档提到情景再现程序,能对天气和危化源做细节与总体分析,输出报告、图表、等值点。要做「再现」,前提是数据能回放到当时的每一秒。这里有三样东西必须在设计阶段就定下来:
| 留存项 | 粒度 | 建议保留期 | 用途 |
|---|---|---|---|
| 原始数据帧 | 每条上报,含状态位 | 不少于 12 个月 | 复算、争议时的原始依据 |
| 换算后浓度 | 与原始帧一一对应 | 不少于 24 个月 | 报表、趋势分析 |
| 设备与点位档案 | 变更时留版本 | 长期 | 定位到具体罐区与设备 |
| 告警与操作日志 | 每次置位、确认、复位 | 不少于 24 个月 | 责任界定、流程复盘 |
时间同步是这套体系的地基。多节点数据要对齐到同一时间轴,靠的是统一的时钟源,常见做法是中心侧跑时间服务、终端定期校时,并且把校时偏差本身也记进日志。偏差超过设定门限的设备要标记出来,因为一条时间戳错了几十秒的记录,在事故回溯时可能把因果顺序彻底颠倒。
原始帧留存还有一层价值:模型参数是可以改的,阈值是可以调的,但原始读数不会变。事后如果有人质疑当时的判断,能拿出原始帧重新算一遍,比任何解释都有力。这就是我一直说的「后悔药」,平时占点存储,用上一次就值回全部成本。
5. 部署联调避坑:5 个现场翻车点与对应解法
这套系统的失败模式很有规律,绝大多数不是设备坏,而是参数和现场条件没对齐。下面五条是我在类似项目里反复见到的真实形态,按「现象 → 原因 → 解决」写,每条都能对应到一个可执行的检查动作。
5.1 硬件与供电侧的三笔账
第一坑:读数长期稳定得可疑。现象是某几个点连续几周数据几乎不动,曲线平得像画上去的。原因往往是探头进气口被粉尘、油雾或水汽糊住,或者标定早就过期,传感器在「假饱和」状态下输出一个恒定值。解决要三条一起上:安装朝向改成向下倾斜 45 度并加防尘透气罩;把标定周期写进运维计划并做成工单;在软件里加健康度指标,用响应时间和零点漂移做判据,数据太「完美」反而要报警提示核查。
第二坑:中继站一到连续阴雨天就集中掉线。现象是晴天一切正常,连下三天雨之后几个中继同时失联,天晴后又自己恢复。原因是电池容量按平均功耗算的,没考虑低温衰减和放电深度,太阳能板还被旁边的高塔或管廊在冬季低角度下遮了一部分。解决是把容量计算改成按自持天数反算,并把低电压状态做成主动上报项,让运维在掉线前就收到消息;板子安装位置要在冬季正午前后实测遮挡,不能只看夏天。
第三坑:GPS 在罐区漂移,事后对不上点。现象是同一台设备在钢结构密集区上报的坐标能跳几十米,事后复盘时无法确认到底在哪个罐组。原因是多径和遮挡,这不是设备问题也不是调参能解决的问题。解决是双轨制:点位编号写进设备配置作为主键,GPS 只做辅助和移动终端的轨迹参考;同时把点位档案和地图绑定,让报表始终按点位编号出,不按坐标反查。
5.2 网络与软件侧的两笔账
第四坑:网络一直在线,告警总是慢半拍。现象是设备心跳正常、后台显示全绿,但真实泄漏时告警比现场目击晚了几十秒甚至更久。原因通常是多跳排队加路由震荡,重路由期间缓存被丢弃,重传又把队列进一步拉长。解决要三件事:限制最大跳数,超过三跳的路径宁可增设中继;给告警帧设高优先级队列,和普通周期上报分开调度;把「每小时重路由次数」做成监控指标,超过门限就派人查链路质量而不是等它自己恢复。
第五坑:扩散模型算出的范围和现场目测差一个量级。现象是报告里的等值线图看着很专业,但和现场人员描述的影响范围完全对不上。原因有三个高频来源:物质库条目选错(同分异构体、混合物、商品名与化学名不一致);源强直接按传感器满量程代入,高估了泄漏速率;气象数据取自远离风险源的测点,风向本身就偏了。解决是建三张表——现场物质映射表、源强分级估算表、气象测点与风险源的对应关系表,三张表在上线前必须逐项核对并签字确认,模型输出的每一份报告都要带假设条件附录。
6. 把案例变成可验收的清单:在线率、告警时延与一次复算
看完文档最容易犯的错,是照着架构图把设备买齐、装完、通电,然后觉得项目结束了。真正的分水岭在验收:你能不能拿出一组数字,证明这套系统在连续运行、部分节点故障、真实告警三种状态下都达标。我习惯用的验收指标就六项,覆盖、入网、丢包、续航、告警时延、数据留存,每一项都要有明确的测试方法和合格线:
| 验收项 | 测试方法 | 参考合格线 |
|---|---|---|
| 区域覆盖率 | 网格化校核 + 现场抽测接收电平 | 重点区域 100%,一般区域不低于 95% |
| 入网成功率 | 全节点上电,统计首次上报 | 24 小时内不低于 99% |
| 端到端丢包 | 连续 72 小时心跳统计 | 低于 1% |
| 终端续航 | 满电静置运行至低电压告警 | 不低于设计自持天数的 90% |
| 告警时延 | 标准气体标定,记录置位时间 | 95 分位小于 5 秒 |
| 数据留存 | 抽查任意历史时段的原始帧 | 可完整回放,时间偏差在门限内 |
验收时我不看厂家提供的截图,只看自己导出的原始数据。下面这段脚本是我每次必跑的复算,读 24 小时导出的 CSV,算单设备在线率和告警时延,专治「后台显示一切正常」:
import csv from datetime import datetime def parse(ts): return datetime.strptime(ts, "%Y-%m-%d %H:%M:%S") SAMPLE_S = 60 # 设计上报周期,秒 GAP_LIMIT = SAMPLE_S * 3 # 超过 3 个周期没数据,判定为掉线 rows = [] with open("export_24h.csv", encoding="utf-8") as f: for r in csv.DictReader(f): rows.append(r) # 1) 单设备在线率:按时间排序后统计超时缺口 by_dev = {} for r in rows: by_dev.setdefault(r["device_id"], []).append(parse(r["ts"])) for dev, ts_list in by_dev.items(): ts_list.sort() gaps = [(b - a).total_seconds() for a, b in zip(ts_list, ts_list[1:])] offline = sum(1 for g in gaps if g > GAP_LIMIT) total = len(gaps) + 1 print(f"{dev}: 上报 {total} 次,掉线缺口 {offline} 个,在线率 {(1 - offline / total):.2%}") # 2) 告警时延:标气注入时刻到系统置位时刻的差值 for r in rows: if r.get("alarm_ts"): delay = (parse(r["alarm_ts"]) - parse(r["ts"])).total_seconds() print(f"{r['device_id']} 告警时延 {delay:.1f} 秒")SAMPLE_S要按项目实际配置改,GAP_LIMIT取三倍周期是为了容忍偶发重传,取太紧会把正常抖动算成掉线。在线率按「缺口数 / 总间隔数」算而不是按分钟数算,是因为前者对长掉线更敏感,能一眼看出哪些设备是真的断过。告警时延那段假设 CSV 里同时有数据时间和置位时间两列,实际导出时字段名可能不同,改字段名就行,逻辑不用动。
血泪经验是:这套复算一定要在验收会上现场跑,用当天导出的数据,不要用提前准备好的样本。我见过太多「演示环境完美、现场数据一团」的情况,也见过自己偷懒只看后台面板、结果三个月后业主拿原始数据一算在线率只有八成多的尴尬。从那以后我每次交付前都强制走一遍这个复算流程,数据对不上就先查采集链路,绝不先改报表。希望帮到你。
本文还有配套的精品资源,点击获取