
简介WHB-870系列微机装置103规约点表面向微机保护装置的调试、运维与二次开发人员用于解决103规约接入时点号对照与信息点解析缺少权威参照的问题适合电力系统自动化、变电站综自改造等场景下的技术人员使用。压缩包共1个pdf文件约162KB为V1.00版本点表文档。内容按保护动作故障信号、告警信号、状态信号三大类编排逐条列出信息点名称、报文类型、INF点号与公共地址并给出线路、充电、厂用变、电容器、电动机五类保护对象的FUN地址对应关系如178、211、199、185、227对过流Ⅰ至Ⅲ段、零序、负序、低零序、过热、重合闸及各类压板状态均有标注带★者说明为选配项需装置配置交流插件2时才有点号。凭借清晰的表格结构与可选配说明读者可快速完成报文解析、点表建模与装置联调核对。该文档已有273人学习下载适合用作规约配置与故障信号排查的案头参考。1. 一次“装置灯亮了主站没反应”背后的 103 规约点表馈线过流Ⅱ段跳闸灯亮了开关也确实分了后台主站的告警窗却干干净净。二次回路查完通信链路也通最后问题落在 103 规约点表上装置里这个点的 FUN 是 199厂用变主站数据库却按 178线路建的点报文规规矩矩发上来了主站找不到落点直接当未知 INF 丢掉。WHB-870 系列把 WHB-871、WHB-872、WHB-876、WHB-877 四类装置的 103 规约点表合并成一份 V1.00 文档按保护动作故障信号、告警信号、状态信号、控制、遥测、电度、总召唤、录波八块逐点给出 INF、报文类型、FUN 和公共地址。这份表不是给运维翻着玩的它是微机保护装置与变电站自动化主站之间唯一的地址契约抄错一列现场就得整站重新对点。2. 拆解点表的四个寻址维度FUN、INF、ASDU 与公共地址一份 103 规约点表看起来是几十行表格本质上是四个维度在做联合寻址报文类型ASDU决定这条报文“长什么样、干什么用”FUN 决定“是哪个保护对象”INF 决定“是这个对象下的哪一条信息”公共地址决定“是哪一台装置”。四个都对上主站才能把一条上送报文准确落到某个具体测点上。少对任何一个报文就变成一条无法解析的裸数据。2.1 FUN 地址按保护对象分档一张表定死WHB-871 是典型的“一台装置顶多套保护”设计同一套软硬件通过配置成线路、充电、厂用变、电容器、电动机五种保护对象来适配不同间隔。区分手段就是 FUN文档里单独给了一张对应关系表。保护对象线路充电厂用变电容器电动机FUN 地址178211199185227这张表是整个点表的地基。WHB-871 的后续章节里很多行只在对应的保护对象列打勾读的时候必须横向看到底哪些列有勾再回头查 FUN 表。WHB-872微机电动机保护测控装置把 FUN 固定成 227WHB-876微机电压互感器监控装置固定成 187WHB-877微机备用电源自投装置固定成 248。也就是说后三种装置的 FUN 是装置级常量只有 WHB-871 需要按间隔对象做映射。实际配置时我一般先把这张对照表做成一个字典落在脚本里后面所有点都靠它换算避免手抄。# WHB-871 保护对象到 FUN 的映射其它型号用固定值 FUN_TABLE { WHB-871: {线路: 178, 充电: 211, 厂用变: 199, 电容器: 185, 电动机: 227}, WHB-872: {default: 227}, # 电动机保护测控FUN 恒定 WHB-876: {default: 187}, # 电压互感器监控FUN 恒定 WHB-877: {default: 248}, # 备自投FUN 恒定 } def resolve_fun(device, obj_typeNone): 按装置型号和保护对象解析 FUN后三种装置忽略 obj_type table FUN_TABLE[device] return table.get(obj_type, table.get(default))resolve_fun的入参是装置型号加保护对象返回该点应填的 FUN。对 WHB-872/876/877 传obj_typeNone也能正确返回默认值这样四种装置可以走同一套解析逻辑不用在主流程里写分支。2.2 (FUN, INF) 才是联合主键单看 INF 必然撞车新手最容易犯的错是把 INF 当成全局唯一编号。WHB-871 的告警信号里INF 221 同时对应“低零序过流告警”状态信号里INF 221 又对应“重合闸充电标志”。如果只拿 INF 建库这两条直接主键冲突。正确做法是把(装置, 保护对象, 报文类型, FUN, INF)作为联合键。# 检测同一 ASDU FUN 下 INF 是否重复重复即视为建模冲突 from collections import defaultdict import csv bucket defaultdict(list) with open(whb870_points.csv, encodingutf-8-sig) as f: for row in csv.DictReader(f): # row 需包含 device/obj/fun/asdu/inf/name 字段 key (row[device], row[obj], row[asdu], int(row[fun]), int(row[inf])) bucket[key].append(row[name]) for key, names in bucket.items(): if len(names) 1: print(冲突点:, key, -, names)这段脚本遍历整理好的 CSV按联合键归集点位名称。输出为空说明建模干净如果有输出先别急着删通常有两种情况一是同一物理量在不同 ASDU 下确实有两套 INF下面 2.3 节讲二是抄表时把列串了。区分办法就是看asdu字段是否相同相同才算真冲突。2.3 ASDU 决定语义别拿遥信的 INF 去建遥控点103 规约的报文类型号不是编号是语法声明。WHB-870 点表里出现的几类各有分工ASDU_1承载带时标的单点遥信是告警、状态这类信号的主通道ASDU_2承载带相对时间的单点事件保护动作跳闸走这条ASDU_70常与ASDU_2成对出现同一动作既发事件也发遥信ASDU_20是遥控命令压板投退、信号复归、定值区切换都从这里下发ASDU_41是双点开入ASDU_50走遥测ASDU_36走电度脉冲ASDU_64用于断路器遥控输出。对照 WHB-871 的控制表就会发现问题状态信号里“低零反时限压板”是 INF 175控制表里同一个压板却是 INF 65。这不是抄错而是遥信区和遥控区各自维护了一套 INF 编号空间。建点时如果偷懒把遥信的 INF 直接复制到遥控点装置收到命令后会解析成完全不相干的另一个对象严重时误跳。-- 主站侧点位表ASDU 必须进主键否则遥信/遥控会互相覆盖 CREATE TABLE whb870_point ( device VARCHAR(16) NOT NULL, -- 装置型号如 WHB-871 obj_type VARCHAR(16) NOT NULL, -- 保护对象线路/充电/厂用变/电容器/电动机 asdu VARCHAR(16) NOT NULL, -- 报文类型如 ASDU_1 / ASDU_20 fun SMALLINT NOT NULL, -- 功能类型地址 inf SMALLINT NOT NULL, -- 信息序号 com_addr SMALLINT NOT NULL DEFAULT 1, -- 公共地址文档注明统一为 1 point_name VARCHAR(64) NOT NULL, optional BOOLEAN NOT NULL DEFAULT FALSE, -- 星号标记的可选配项 PRIMARY KEY (device, obj_type, asdu, fun, inf) );asdu进主键是关键一步它把遥信、遥控、遥测三类点彻底隔开。optional字段对应文档里带星号的条目导入组态时可以先按optional FALSE过滤把必配点先跑通再逐批放可选点避免一次导几百个点连不上还查不出是谁的问题。2.4 公共地址统一为 1正文行尾的其它数字别乱搬文档开头明确写了公共地址统一为 1这是全表最省事的一条约定。但逐行读状态信号和控制两节会发现有些行在末尾还跟着一个 0 或 2 的数字。这两个数字不是要你改公共地址而是表内不同小节列序不统一造成的视觉错位——有的小节列序是“信息点名称 INF 报文类型 公共地址 FUN”有的是“信息点名称 报文类型 INF FUN 公共地址”。抄表时把列序当成固定模板按位置截取必然串列。稳妥的处理方式是按小节分别声明列名再解析而不是写死列号# 不同小节列序不同按小节显式声明列名 SECTION_COLUMNS { 1.1 保护动作故障信号: [name, asdu, inf, fun, com_addr], 1.3 状态信号: [name, inf, asdu, com_addr, fun], 1.4 控制: [name, inf, asdu, com_addr, fun], } # 统一落库时把 com_addr 强制归一到文档约定的 1 row[com_addr] 1这段代码解决两个问题一是列序差异二是把行内出现的杂散数字统一收敛到公共地址 1。收敛这步建议保留即使某天文档真改了约定改一行常量比改几百个点划算。3. 把点表落成可维护的数据结构从手工抄表到脚本生成手工把上千个点敲进组态软件出错概率几乎是一百。真实项目里我一般分三步走先把点表摊平成标准 CSV再用脚本体检最后生成组态软件能直接吃的导入文件。三步之间靠固定字段名衔接任何一步发现问题都能回退重跑。3.1 把八个小节摊平成同一张宽表八个小节的字段其实能归并到同一组列装置型号、保护对象、报文类型、FUN、INF、点名称、是否可选配、所属小节。难点在于 WHB-871 的小节用打勾表示适用对象一个点可能同时适用五个对象中的四个这就要做“一拆多”。OBJ_ORDER [线路, 充电, 厂用变, 电容器, 电动机] def expand_871_section(section_rows, deviceWHB-871): 把带勾选列的小节展开成一行一个 (点, 对象) 的记录 out [] for row in section_rows: marks row[marks] # 形如 [True, False, True, True, True] for obj, marked in zip(OBJ_ORDER, marks): if not marked: continue out.append({ device: device, obj: obj, asdu: row[asdu], fun: FUN_TABLE[device][obj], inf: int(row[inf]), name: row[name], optional: row[optional], }) return outmarks是按表头顺序排好的布尔列表来自人工整理或 OCR 校正后的中间文件。zip把它们和保护对象对齐只输出打了勾的组合。WHB-871 一行五点的情况很常见展开后点数量会膨胀几倍这是正常的——主站本来就是按“间隔 点”建点的。3.2 用脚本做一次全表体检摊平之后立刻体检重点看三类问题同一(device, obj, asdu, fun, inf)重复、INF 超出装置声明范围、可选配点是否在非选配配置里被启用。# 体检结果落文本方便和现场配置逐条比对 python check_points.py --input whb870_points.csv \ --out report.txt \ --strict-optional三个参数的作用--input指定摊平后的 CSV--out把冲突和越界行写进文本报告不带这个参数只打屏长表刷屏会漏看--strict-optional打开后凡optional TRUE而装置实际未装交流插件 2 或信号插件 2 的点会全部列出来交付前拿这份清单跟现场核对一次能省掉大量返工。体检报告里最常见的一类告警是“点号跳跃”。WHB-871 某保护对象的 INF 从 54 跳到 59、再跳到 60中间空号不是漏抄是给未选配功能预留的。这类空号不用补但组态软件如果按连续地址段建点会直接报错。3.3 生成组态可导入的 CSV 与点号对照表体检通过后生成两份产物一份给主站组态导入一份给现场调试用的点号对照表。前者字段名严格按组态软件的模板后者保留中文点名称和打勾信息方便调试时肉眼找。产物用途关键列组态导入 CSV主站建点点号、点名、ASDU、FUN、INF、公共地址、点类型点号对照表现场对点保护对象、INF、中文点名、可选配标记遥测偏移表遥测/电度建点起始 INF、对象数、每对象宽度遥测和电度有个共同特点它们不逐点列只给一个起始 INF后面按固定宽度往后排。WHB-871 的遥测从 INF 92 开始WHB-872、WHB-876 同样从 92 开始电度脉冲从 INF 6 起正向有功、反向有功、正向无功、反向无功依次 6、7、8、9。建点时按这个起点加序号铺开序号错一位后面所有遥测全串。4. 解析 WHB-870 点表时最容易踩的五个坑点表本身不难难在文档里藏着几条“读起来像废话、出问题时才知道要命”的规则。下面这几条是我在不同项目里反复遇到的每一条都对应过实际故障。4.1 ASDU_41 在总召唤时改成 ASDU_40 上送点表在总召唤一节写得很直白ASDU_41的 INF 在总召唤时改成对应的ASDU_40上送。意思是同一个双点开入合位、跳位、手跳、弹簧未储能、隔离刀位置这些平时主动上送走ASDU_41主站发总召唤时走ASDU_40。主站如果只按ASDU_41建了映射表总召回来的ASDU_40报文会全部落到未定义区。排查时表现为装置主动变位能收到总召后画面却不刷新。解决办法是在主站的解析表里为同一个 INF 同时注册ASDU_40和ASDU_41两个入口指向同一个点对象。4.2 定值区变化在总召唤时不上送同一条说明里还有半句定值区变化在总召唤时不上送。ASDU_1的 INF 224定值区变化只在定值区真正切换时主动上送一次总召响应里不会带它。这意味着主站重启后做一次总召定值区号是拿不到的必须额外读一次定值区当前值或者等下一次定值区切换。现场最常见的误判是“主站重启后定值区显示为 0以为装置掉了定值”。实际定值一点没丢只是这个点不走总召通道。组态时把它标记成“事件型”而非“状态型”画面上就不会因为它为空报警。4.3 星号可选配项与插件差异带星号的点全部依赖硬件插件带星号的保护多数要求装置选配交流插件 2带星号的开关量要求选配信号插件 2。同一型号装置装不装插件点号集合完全不同。更麻烦的是录波通道数也跟着变。处理办法是把optional和插件型号做成两个字段一起进库导点前先确定现场实际插件配置。-- 只导出当前插件配置下真正存在的点 SELECT point_name, asdu, fun, inf FROM whb870_point WHERE device WHB-871 AND obj_type 厂用变 AND (optional 0 OR plugin_ac2 1); -- plugin_ac2 表示是否装交流插件 2这份查询在交付前跑一遍能把“装置根本没这功能、主站却建了点”的僵尸点清掉。僵尸点常年不变位最容易在事故分析时干扰判断。4.4 多保护对象共用一台装置时的 FUN 错配WHB-871 一台装置可配五种保护对象FUN 各不相同。现场改扩建时经常出现“同一个间隔从线路改成充电”的情况装置侧改了配置主站侧 FUN 忘了改于是所有报文都对不上。判断方法很直接拿装置侧实际发出的 FUN 去比对主站建点用的 FUN不一致就是错配。提示 改扩建后不要只对单个跳闸点把该 FUN 下的动作、告警、状态、控制四类点各抽一条做全链路验证四类都通才算改完。4.5 遥控 INF 与遥信 INF 是两套编号空间这一条在 2.3 节提过值得单独强调。压板类对象在状态信号和状态遥信里用一套 INF在控制遥控里用另一套两套编号互不相干。WHB-871 的“低零反时限压板”遥信是 175、遥控是 65两者相差一百多肉眼很难发现抄错。建库时给 ASDU 加前缀做人工分组比如把遥控点统一命名成YK_开头导入前再做一次“同名不同号”的交叉比对能在交付前拦掉大部分低级错误。5. 录波通道地址编排与主站联调验证技巧录波是这份点表里唯一按“通道序号”而不是按 INF 组织的部分也是最容易被忽略、出故障时又最需要它的部分。WHB-871、872、876 的录波通道规则并不完全一致交付前值得单独核一遍。5.1 模拟量从 1 起排开关量接模拟量的尾巴三份装置的模拟量通道都从 1 开始依次加 1。开关量的起点则取决于模拟量占了多少个通道WHB-872 模拟量 8 个通道Ia1、Ic1、Ia2、Ic2、3I0、Ua、Ub、Uc开关量从 9 开始WHB-876 同样是 8 个模拟量Ua1、Ub1、Uc1、Ul1、Ua2、Ub2、Uc2、Ul2开关量也从 9 开始WHB-871 的开关量起点不是一个固定数而是“模拟量的最后一个加 1”因为不同保护对象的模拟量数量本身不同。以 WHB-871 选配交流插件 2 为例线路、充电、电容器、电动机是 7 个模拟量通道厂用变多出 U0、Ubp共 9 个。对应的开关量起点就分别是 8 和 10不存在统一的“从 9 开始”。工程师站配置录波通道时必须按装置实际保护对象去推这个起点。5.2 选配与未选配交流插件的两套开关量基准WHB-871 的开关量录波表给了两套选配交流插件 2 时线路合位从通道 8 起未选配交流插件 2 时模拟量只剩 Ia、Ib、Ic 三个合位从通道 5 起。同一份点表里两套序号并存配置时一定要先确认插件状态再选对应那一列。装置插件状态模拟量通道开关量起始通道WHB-871选配交流插件 27 或 98 或 10随对象WHB-871未选配交流插件 235WHB-872—89WHB-876—89通道序号错位不会导致通信中断只会让录波波形张冠李戴本该显示 A 相电流的通道里出现零序电压。事故分析时如果先入为主地相信通道标签结论会完全跑偏。5.3 用总召唤加定值区切换做一次闭环验证点表交付前我一般用三个动作做闭环先发总召唤验证所有ASDU_1和转换后的ASDU_40点位能正确刷新再手动切一次定值区验证 INF 224 主动上送且总召里不出现最后投退一块压板验证遥控 INF 下发的对象和遥信 INF 回读的对象是同一个。# 用装置调试口抓一段报文确认总召与定值区事件都在预期通道上 python i103_trace.py --port /dev/ttyUSB0 --baud 9600 \ --filter ASDU_1,ASDU_40,ASDU_41 \ --save trace.log--filter只保留关心的报文类型避免总召期间刷屏--save把原始报文落盘事后可以拿点位表逐条比对。三个动作跑完点表里 90% 的坑都会在交付前暴露出来。剩下那 10%多数藏在可选配点和录波通道序号的边界上只能靠现场核对。本文还有配套的精品资源点击获取