ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CSV to IEC61850 CID 转换器设计

CSV to IEC61850 CID 转换器设计 1. 引言1.1 项目背景IEC 61850 是电力自动化领域的重要标准其中 CIDConfigured IED Description文件描述了智能电子设备IED的配置信息包括数据集、报告控制块、数据实例等。在工程实践中往往需要从 CSV 表格导入配置数据自动生成符合标准的 CID 文件以提高配置效率和准确性。1.2 目的与目标本程序旨在提供一个图形化工具通过解析用户定义的 CSV 文件结合 IEC 61850 数据类型模板DataTypeTemplates.xml生成完整的 CID 文件。主要目标包括支持多逻辑设备LDevice配置LDevice 实例名取自 CSV。自动为每个数据集生成报告控制块仅当数据集包含 ST/MX 类型数据。根据 CSV 中的描述desc填充 DOI 的 desc 属性和 dU 的值。支持 CSV 中指定数据属性DAI的 sAddr 属性。对 CSV 中出现的所有 DO/DA 路径进行模板存在性校验确保配置与模板一致。提供详细的调试日志窗口方便用户排查问题。2. 系统概述2.1 功能简介程序通过 PyQt6 构建图形界面主要流程如下用户选择 CSV 文件可自动检测编码和数据类型模板 XML 文件。点击“Parse CSV”按钮预览 CSV 数据。点击“Generate CID”按钮程序解析 CSV、验证模板、生成 CID 文件并弹出保存对话框。底部的调试窗口实时显示解析过程中的警告、错误和统计信息。2.2 技术栈编程语言Python 3GUI 框架PyQt6数据处理csv 模块标准库、xml.etree.ElementTree标准库编码检测尝试常用编码utf-8, gbk, gb2312, ansi, cp12523. 功能需求3.1 核心功能CSV 解析读取 CSV 文件支持多种编码自动检测。数据类型模板加载解析 DataTypeTemplates.xml提取 LNodeType、DOType、DAType、EnumType。逻辑节点LN实例化根据 CSV 中出现的 LNType 自动创建 LN 元素并为每个 LN 下的 DO 生成 DOI 及其子 DAI。数据集生成根据 CSV 中 TypeDataset 的行为每个数据集名称收集 FCDA 列表生成 DataSet 元素。报告控制块生成仅当数据集所有 FCDA 的 FC 为 ST 或 MX 时生成 ReportControl并根据 FC 类型决定缓冲属性ST→缓冲MX→非缓冲混合→缓冲并告警。报告属性包括 intgPd30000, rptIDNULL, bufTime100 等TrgOps 和 OptFields 按示例固定。DOI 描述映射将 CSV 中的 Desc 列设置为对应 DOI 的 desc 属性并用于填充 dU 的值。sAddr 属性将 CSV 中的 sAddr 列设置为对应 DAI 的 sAddr 属性支持复合 DA 路径如 mag.f。多 LDevice根据 CSV 中的 LDName 列创建多个 LDeviceLDevice 顺序与 CSV 中首次出现顺序一致每个 LDevice 下拥有独立的 LLN0。prefix 支持CSV 中的 prefix 列应用到 FCDA 和 LN 元素。模板存在性校验对 CSV 中每一行包括 Dataset 和 Control的 DO 和 DA 路径递归检查是否在模板中存在若不存在则报错并终止生成。LN 重复性校验同一 LDevice 下不允许出现相同的 (prefix, lnClass, lnInst) 组合。数据集 FCDA 数量限制单个数据集的 FCDA 数量超过 256 时报错。FCDA 简化生成的 FCDA 中不包含 daName 属性。3.2 高级特性自动为 LLN0 创建默认实例若 CSV 中未定义。报告按 LDevice 分组每个 LDevice 内先放置所有 DataSet再放置所有 ReportControl。支持排除特定 DO如 SV和特定 DAI如 subEna, subVal 等取代相关 DAI的实例化。跳过 fcCF 的 DAI 实例化。4. 系统架构4.1 总体架构程序采用 MVC 风格的单窗口架构由以下几部分组成视图层MainWindow 类PyQt6包含文件选择、按钮、表格、日志窗口。控制层MainWindow 的事件处理方法parse_csv, generate_cid负责协调数据流。模型层DataTypeResolver 类模板解析与查询、CSV 解析函数、CID 生成函数generate_cid。4.2 模块划分CSV 解析模块parse_csv函数自动检测编码返回列表字典。模板解析模块DataTypeResolver类解析 XML 并构建类型字典提供类型查询、默认值获取、路径验证等功能。数据收集与验证模块在MainWindow.generate_cid中分多步收集原始数据、验证 LN 重复性、验证模板路径、构建最终数据结构。CID 生成模块generate_cid函数接收处理好的数据结构构造 SCL 树并写入文件。日志模块通过log_message回调将信息输出到调试窗口。5. 模块设计5.1 DataTypeResolver 类属性lnode_types,do_types,da_types,enum_types字典ID 到对应 XML 元素的映射。方法_parse()遍历模板根节点填充各字典。get_ln_type(type_id)、get_do_type(type_id)、get_da_type(type_id)返回对应元素若不存在则记录警告。get_enum_default(enum_type_id)返回枚举类型中ord最小的枚举值文本。verify_do_da_path(ln_type_id, do_name, da_full_path)递归验证给定 LN 类型下是否存在指定 DO 的 DA 路径。利用_find_da_in_do_type和_find_bda_in_da_type实现。generate_doi_for_ln(...)核心方法为指定 LN 生成所有 DOI。遍历 LNodeType 的 DO 元素为每个 DO 创建 DOI调用_generate_dai_for_do递归生成 DAI并在控制 DO 时强制注入 ctlModel/sboTimeout。_generate_dai_for_do、_generate_bda_for_da_type、_create_dai递归处理 DOType 和 DAType生成 DAI 或 SDI并根据模板默认值、CSV 描述、sAddr、控制标志等设置值。5.2 数据收集与验证模块位于MainWindow.generate_cid中分为多个步骤收集原始数据遍历所有 CSV 行仅 Dataset 和 Control提取raw_ln_info键 (ld, prefix, ln_inst, ln_type) → True用于后续 LN 实例收集。raw_fcda_list仅 Dataset 行存储数据集信息。raw_do_desc键 (ld, prefix, ln_inst, ln_type, do_name) → desc用于 DOI 描述。raw_dai_saddr键 (ld, prefix, ln_inst, ln_type, do_name, da_name) → sAddr。validation_items存储 (ld, prefix, ln_inst, ln_type, do_name, da_name) 用于模板验证。LN 解析与重复性校验遍历raw_ln_info通过dt_resolver.get_ln_type获取 lnClass构建ln_candidates列表。检查重复 LN同一 LD 下 (prefix, ln_class, ln_inst) 是否重复若重复则报错退出。构建最终ln_instances字典键 (ld, prefix, ln_class, ln_inst) → ln_type。模板存在性校验遍历validation_items利用dt_resolver.verify_do_da_path验证路径失败则记录并最终报错。构建 do_desc_map、dai_saddr_map将原始键中的 ln_type 替换为 ln_class。构建 control_do_by_ln记录每个 LN 下的控制 DO 名称集合。构建 datasets将raw_fcda_list转换为以数据集名称为键的字典每个 fcda 包含 ldInst, prefix, lnClass, lnInst, doName, daName, fc。5.3 CID 生成模块generate_cid 函数创建 SCL 根元素添加固定的 Header、Communication 块模板化内容。添加 IED 元素并在其中添加固定的 Services 块。创建 AccessPointnameS1和 Server并添加 Authentication。多 LDevice 处理收集所有出现的 LDevice 名称按首次出现顺序构建列表。为每个 LDevice 创建LDevice元素inst属性直接取 LDName。创建 LN 元素先遍历所有 LDevice为每个 LDevice 创建其下的 LLN0若 CSV 中未定义则自动创建默认 LLN0。再创建其他 LN确保 LLN0 位于 LDevice 子节点最前面。数据集与报告分组将数据集按 LDevice 分组ld_datasets。对每个 LDevice先遍历所有数据集生成DataSet元素再遍历所有数据集生成ReportControl元素实现所有数据集在前、所有报告在后的顺序。报告生成逻辑检查数据集所有 FCDA 的 FC 集合若不为 {ST}、{MX} 或 {ST,MX} 则跳过。根据 FC 集合确定缓冲属性、entryID 值。设置报告属性namebrcb/urcb数据集名首字母大写、datSet、intgPd30000、rptIDNULL、confRev1、buffered、bufTime100。添加 TrgOps 和 OptFields 子元素按示例固定。DOI 生成遍历所有 LN 元素调用dt_resolver.generate_doi_for_ln传入对应 LN 的 do_desc_map、dai_saddr_map 和控制 DO 集合。在generate_doi_for_ln内部处理完模板中的 DAI 后若 DO 在控制集合中则强制添加/覆盖 ctlModel 和 sboTimeout。添加数据类型模板深拷贝后附加。写入文件使用 ET.indent 美化输出。5.4 GUI 界面MainWindow 类布局垂直布局包含文件选择、IED 名称输入、解析按钮、表格、生成按钮、调试窗口。表格用于预览 CSV 数据自动调整列宽。调试窗口只读 QTextEdit通过log_message方法添加带时间戳的日志自动滚动到底部。按钮事件browse_file选择 CSV 文件。browse_dt_file选择 XML 模板文件加载并初始化 DataTypeResolver。parse_csv解析 CSV 并填充表格。generate_cid执行上述数据收集、验证、生成流程若出错则弹出消息框并记录日志。6. 关键算法与数据结构6.1 CSV 编码检测尝试一系列常用编码utf-8, gbk, gb2312, ansi, cp1252直至成功读取。若全部失败抛出异常。6.2 模板路径验证算法verify_do_da_path采用递归下降方式首先在 LNodeType 中查找指定 DO获取其 DOType ID。然后在 DOType 中按路径段逐步查找若当前段对应 SDO则进入其引用的 DOType若对应 DA 且 bTypeStruct则进入其引用的 DAType若对应 DA 且为叶子则返回成功若对应 BDA类似处理。若任何一步查找失败返回 False 并记录详细日志。6.3 递归生成 DOI/DAIgenerate_doi_for_ln遍历 LNodeType 的 DO为每个 DO 创建 DOI然后调用_generate_dai_for_do处理 DOType 的 DA 和 SDO。_generate_dai_for_do递归遍历 DA 和 SDO对于结构体类型创建 SDI 并进入子结构。此过程中会利用传入的dai_saddr_map键为 (do_name, full_path)为叶子 DAI 设置 sAddr 属性并根据是否控制 DO 和当前 DA 名称决定是否覆盖值为固定值。6.4 多 LDevice 顺序保持使用 OrderedDict 和列表记录首次出现的 LDevice 名称确保生成顺序与 CSV 中首次出现顺序一致。6.5 数据集与报告顺序控制在 generate_cid 中对每个 LDevice 先循环生成所有 DataSet再循环生成所有 ReportControl不混合。6.6 控制 DO 特殊 DAI 注入在generate_doi_for_ln中处理完模板中的 DAI 后通过doi.find检查是否已存在 ctlModel 和 sboTimeout若不存在则创建新的 DAI并设置固定值的Val子元素。这保证了即使模板中未定义这些 DAI最终 CID 中也会出现。6.7 数据结构设计ln_instances{(ld, prefix, lnClass, lnInst): ln_type}用于快速查找 LN 类型。do_desc_map{(ld, prefix, lnClass, lnInst, doName): desc}用于设置 DOI 的 desc。dai_saddr_map{(ld, prefix, lnClass, lnInst, doName, fullDaPath): sAddr}用于设置 DAI 的 sAddr。control_do_by_ln{(ld, prefix, lnClass, lnInst): set(doName)}用于识别控制 DO。datasets{ds_name: {desc: ds_desc, fcda: [fcda_dict]}}其中 fcda_dict 包含 ldInst, prefix, lnClass, lnInst, doName, daName, fc。7. 使用说明7.1 环境准备安装 Python 3.6。安装 PyQt6pip install PyQt6。准备 CSV 文件和数据类型模板 XML 文件。7.2 CSV 格式要求必须包含以下列大小写敏感Type取值Dataset或Control。Name数据集名称仅 Dataset 行需要。LDName逻辑设备实例名如LD0,LD1。prefixLN 前缀可为空。LNInstLN 实例号可为空表示 0。LNType逻辑节点类型 ID必须与模板中的 LNodeType id 匹配。DOName数据对象名称。DAName数据属性完整路径如stVal,mag.f。FC功能约束如ST,MX,CO。Desc描述可选用于 DOI 的 desc 和 dU 的值。sAddrsAddr 属性值可选。示例csvType,Name,LDName,prefix,LNInst,LNType,DOName,DAName,FC,Desc,sAddr Dataset,dsAlm,LD0,,1,SQTECH_GGIO_ALM,Alm1,stVal,ST,遥信1,yx004 Control,,LD0,,1,SQTECH_GGIO_SPC,SPCSO1,Oper.ctlVal,CO,遥控1,yk0007.3 数据类型模板要求必须是有效的 XML 文件包含DataTypeTemplates根元素可位于SCL内或作为根。模板中必须包含所有 CSV 中引用的 LNType、DOType、DAType、EnumType。每个 LNodeType 必须有lnClass属性。7.4 操作步骤运行程序python csv_to_cid.py。点击“Browse CSV”选择 CSV 文件。点击“Browse XML”选择数据类型模板文件。输入 IED 名称默认 IED1。点击“Parse CSV”预览数据。点击“Generate CID”选择保存路径。查看调试窗口中的日志确认无错误后CID 文件生成成功。
返回列表