101、104规约解析

2023-05-16

转载:电网101、104规约解析(Java)_张二狗和苗翠花的博客-CSDN博客_iec101 java

 

1. 前言
最近在研究广东电网的101与104规约,也就是DL/T634.5101-2002和DL/T634.5104-2009。因为要做一个规约解析的软件(基于Android平台的),刚开始接触的也是一头雾水,因为没有接触过这方面的知识,所以就在网上搜索各种技术帖,大神经验什么的。

后来在网上找到了一个软件–IEC8705(报文翻译工具).exe,这个可以解析一些101(平衡式)的实例,效果图贴一下。

但有些还是解析不了,并且在网上也找不到他的源码,所以就很苦恼。也找到一些C++的源码,但是由于技术有限,我看不懂。下面就和大家来看看我写的这个简单的Java语言的规约解析。先贴一下效果图(我就在控制台简单演示一下,没有做可视化界面)。

GitHub地址:https://github.com/mujave/iec 欢迎star哦

2. Java版效果图
3. 规约详细解释
先看一下我总结的关于规约解析的几个图
101的规约总结

å¨è¿éæå¥å¾çæè¿°

104规约总结

å¨è¿éæå¥å¾çæè¿°

 

具体的104协议解释也可以参考 https://blog.csdn.net/wojiuguowei/article/details/79413142

4. 名词解释
这里所说的名词解释,并不是对一些名词的定义的解释,因为这不是我的专业领域,下面我主要针对报文所代表的名词在代码里怎样解释(解析)说一下。

控制域(平衡式)

å¨è¿éæå¥å¾çæè¿°

在报文解析中,我就是按照图里面的取值方法对对应的字节进行取值,然后进行逻辑判断,将结果加到解析结果里面,由于后四位所代表的平衡链路功能码在这里是固定的,所以可以采取枚举或者反射(常量)的方式进行解析
地址域 (以104的信息体地址为例)
在规约中地址才用的低前高后(低位在前高位在后)的规则
例如:68 10 08 00 02 00 09 01 03 00 01 00 01 40 00 2B 02 00(黄色部分为信息体地址)

å¨è¿éæå¥å¾çæè¿°

所以 这个信息体的地址为01 40 00 >> 0x004001=16385

3、时标CP56Time2a

å¨è¿éæå¥å¾çæè¿°

 

	/**
     * 时标CP56Time2a解析
     *
     * @param b 时标CP56Time2a(长度为7 的int数组)
     * @return 解析结果
     */
    public static String TimeScale(int b[]) {

        StringBuilder result = new StringBuilder();

        int year = b[6] & 0x7F;
        int month = b[5] & 0x0F;
        int day = b[4] & 0x1F;
        int week = (b[4] & 0xE0) / 32;
        int hour = b[3] & 0x1F;
        int minute = b[2] & 0x3F;
        int second = (b[1] << 8) + b[0];

        result.append("时标CP56Time2a:20");
        result.append(year).append("-");
        result.append(String.format("%02d", month)).append("-");
        result.append(String.format("%02d", day)).append(",");
        result.append(hour).append(":").append(minute).append(":");
        result.append(second / 1000 + "." + second % 1000).append("\n");

        return result.toString();
    }

4、遥测量的解析
在101的遥测中定义到有三种类型的值,分别是归一化值,标度值,短浮点数,具体的定义大家可以参考“电力101/104规约中遥测量类型转换”,下面我说一下在Java中怎么解析这三种类型的值。直接上代码了。

public class Main {

    public static void main(String[] args) {
        Telemetry telemetry = new Telemetry();
        System.out.println(telemetry.Bytes2Float_NVA(0xa4, 0x6a));// 报文数据的为A4 6A(低位在前,高位在后) ,为0x6AA4
        System.out.println(telemetry.Bytes2Float_SVA(0xa4, 0x6a));// 报文数据的为A4 6A(低位在前,高位在后) ,为0x6AA4

        System.out.println(telemetry.Bytes2Float_IEEE754("3e0779a6"));
        //报文数据 A6 79 07 3E = 0x3e0779a6 = 0.1323(IEEE754 短浮点数)http://lostphp.com/hexconvert/
    }
}

/**
 * 遥测量解析
 *
 * @author zhangyu
 */

public class Telemetry {

    /**
     * 归一化值
     */
    public static float Bytes2Float_NVA(int low, int high) {
        float fVal;
        int nva = (high << 8) + low;
        // 符号位1位,0为正数,1为负数,后面的为补码表示,
        // 正数的补码和原码相同不需要转换。对于负数,先取反码再加1得到补码的补码,就是原码了。
        int symbol = (high & 0x80);//符号位:0表示正数,1表示负数
        if (symbol == 0x80)
            fVal = -1 * (((nva ^ 0xffff) + 1) & 0x7fff);//  (nva ^ 0xffff) + 1 :补码的补码  ,取出后面的15位数据乘上-1得到值
        else fVal = nva;
        return fVal / 32767;//这里的32767值的是一个量纲,一般这个参数是主站和从站商定的
    }

    /**
     * 标度化值
     */
    public static float Bytes2Float_SVA(int low, int high) {
        float fVal;
        int nva = (high << 8) + low;
        int symbol = (high & 0x80);//0表示正数,1表示负数
        if (symbol == 0x80)
            fVal = -1 * (((nva ^ 0xffff) + 1) & 0x7fff);
        else fVal = nva;
        return fVal;
    }

    /**
     * 短浮点数
     *
     * @param data 从低位到高位按顺序
     * @return
     */
    public static float Bytes2Float_IEEE754(String data) {

        return Float.intBitsToFloat(Integer.valueOf(data, 16));
    }
}

 对于短浮点数的计算,在Java的文档里有这样的说明。

å¨è¿éæå¥å¾çæè¿° 

 还有一些ASDU里的信息体的解析过程代码,有点多,就不一一贴出来了
代码已经发布到GitHub,需要的伙伴可以直接下载

5.104规约解析遇到的一些难题

  1. 报文类型的区分
    101报文区分定长和变长两种,而104规约都是变长的报文。但是对于104来说,其控制域决定了104报文分别属于三种类型(I帧S帧U帧)。所以在解析104到控制域的时候,是在解析104的第一个难题。我先说一下我自己的区分逻辑。

å¨è¿éæå¥å¾çæè¿°

 我是用控制域的第一字节去和3做位运算(因为和3做位运算就可以得到第一字节的D1/D0两位),从上面的图中我们可以看到,结果如果是1的话就是S格式,如果是3的话就是U格式,其他 的结果就是I格式的报文。
第二种方式是我在和一个网友交谈中得到的,他是运用奇数或者偶数来区分的,这里我列一个表格 ,这样的话如果第一个字节是偶数就是I帧,否则判断第三字节是0就是U帧。这样也可以区分报文的类型
但是我认为还是做位运算效率会更高,计算奇偶性还需要用到%这样的运算。

位运算的运用
在解析规约的时候,我一般都是运用的位运算(&),这样既可以提高程序的效率,也有助于理解。首先在规约的定义中有很多的一个字节中的不同位代表一个含义,这种时候就运用到了位运算,这样就可以直接将对应位的值提取出来,例如那可变结构限定词这个字节来举个例子。最高位的D7代表的是信息元素地址的连续性,其中0不连续1连续,所以我们只需要拿这个字节和128(0x80)做位运算就可以得到D7这一位,如果结果是10000000就说明是1连续。这个地方更直观一点的判断方法就是((B&0x80)>>7)==1?连续 : 不连续。

å¨è¿éæå¥å¾çæè¿°

时标的解析

å¨è¿éæå¥å¾çæè¿°

 

首先时标这里一共有7个字节,下面对这几个字节的含义以及解析方法做一下解释:

年(byte 7):这里只有后面的7位有效,但是第8位填充的是0,所以这一个字节直接转换形成int就可以了。
月(byte 6):同上
小时(byte 4):同上
分钟(byte 3):同上
日(byte 5[bit 1~5]):第五字节的后5位表示的是日,byte5 & 0x1F 就可以得到(0x1F = 0001 1111),例如第五字节是87(87 = 0x57 = 0101 0111),其中010指的是星期,10111指的是day。这里使用87 & 0x1F就可以得到23。使用87 & 0xE0就可以得到64,然后再用这个结果除以32就可以得到结果,如果说除以32不太理解的话,也可以用结果右移运算64>>5也可以得到结果 。
毫秒(byte 1 and byte 2):这个地方首先是低前高后的问题(这个为题不太明白的可以先翻一下下面的第四个问题),( byte 2 << 8 ) + byte 1 ,这个地方我用一个表格说明一下(例如第一字节是6E,第二字节是2A)。

å¨è¿éæå¥å¾çæè¿°

低前高后的问题

这里讲一下低前高后的问题,拿这个104规约的信息对象地址举例。例如34 12 00这是原报文的字节,再具体解析的时候我们要把它转成0x001234=4660,其实这里和上面的毫秒的解析方式一样。、

å¨è¿éæå¥å¾çæè¿°

 ————————————————
版权声明:本文为CSDN博主「张二狗和苗翠花」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ZhangYu971014/article/details/79841555

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

101、104规约解析 的相关文章

  • c语言编程软件有哪些 Win7下用哪种C语言编译器

    C语言是一门历史很长的编程语言 xff0c 其编译器和开发工具也多种多样 xff0c 其开发工具包括编译器 xff0c 现举几个开发工具供大家选择 xff0c 当然也要根据自己的操作系统来选择适合自己的开发工具 好多刚开始接触c语言的朋友都
  • 大数据时代的图表可视化利器——highcharts,D3和百度的echarts

    还记得阿里巴巴那个令人澎湃激情的双十一吗 xff1f 还记得淘宝生动形象地把你的的消费历程一一地展示给你看吗 xff1f 还记得那些酷炫拽的it报告图表吗 xff1f 在这个大数据越来越盛行的年代 xff0c 怎样去表达一些用户的关系 xf
  • 在tinycorelinux上安装lxc,lxd (1)

    本文关键字 xff0c 在tinycorelinux上安装lxc xff0c lxd gcc4 4 self reference struct typedef 在前面的文章中我们讲到过内置虚拟化的os设计 xff0c 它可以使包括裸金属 x
  • STM32上第一个程序-GPIO控制LED-第3季第5部分-朱有鹏-专题视频课程

    STM32上第一个程序 GPIO控制LED 第3季第5部分 759人已学习 课程介绍 本课程是 朱有鹏老师单片机完全学习系列课程 第3季第5个课程 xff0c 从零开始带大家写代码控制板载LED xff0c 并且用三个版本的开发板都实现了功
  • Cas 5.3x cas-overlay-template用iframe实现登录跳转

    Cas 5 3x cas overlay template用iframe实现登录跳转 在上一篇Cas 5 3x 简单配置 xff0c 解决https访问的问题的基础上 xff0c 我尝试了一下如何用iframe实现登录和跳转 xff0c 因
  • Linux自带防火墙基本使用

    文章目录 四 Linux自带防火墙1 查看linux的防火墙状态2 查看已经对外开放的端口3 开放端口 重载防火墙配置4 filewalld常用命令 四 Linux自带防火墙 前言 xff1a CentOS7 端口的开放关闭查看都是用防火墙
  • BGP边界网关协议基础知识点

    BGP xff1a 边界网关协议 AS 自治系统 由单一机构或组织管理的一系列IP网络机器设备的集合 网络范围太大 xff0c 协议跑不过来 xff0c 需要进行划分自治管理 为了方便区分和标定不同AS xff0c 我们给每个自治系统设计了
  • 温湿度传感器SHTC3驱动开发(一)小白也能轻松理解

    一 首先了解设备硬件原理图 首先在公司干活 xff0c 要你开发一个设备驱动 xff0c 那你的老大必须得给你的东西如下 xff1a 开发板主板硬件原理图驱动设备的硬件原理图驱动的设备的数据手册 xff08 datasheet xff09
  • nodejs的版本管理工具(nvm)

    1 nvm是什么 nvm全名node js version management xff0c 顾名思义是一个nodejs的版本管理工具 为了解决node各种版本存在不兼容现象 nvm是让你在同一台机器上安装和切换不同版本的node的工具 x

随机推荐

  • A变为a和a的ASCII值

    span class hljs comment include lt stdio h gt span main char ch span class hljs keyword printf span span class hljs stri
  • 机器学习python Kmeans聚类

    import numpy as np import matplotlib pyplot as plt import pandas as pd from sklearn cluster import KMeans from sklearn i
  • 为wget命令设置代理

    实验环境 xff1a ubuntu 12 04 LTS goagent 方法一 在环境变量中设置代理 export http proxy 61 http 127 0 0 1 8087 方法二 使用配置文件 为wget使用代理 xff0c 可
  • ubuntu14.04安裝numpy,scipy

    在windows下搞python xff0c 实在出错太多 xff0c 就安装了双系统 xff0c 在ubuntu下试着学习一下 xff0c 我的ubuntu版本为ubuntu14 04 以前不知道python的这些包之间是有依赖关系的 x
  • STM32的中断体系和FSMC控制LCD-第3季第7部分视频课程-朱有鹏-专题视频课程

    STM32的中断体系和FSMC控制LCD 第3季第7部分视频课程 861人已学习 课程介绍 本课程是 朱有鹏老师单片机完全学习系列课程 第3季第7个课程 xff0c 本课程详细讲解STM32的外部中断和FSMC模块 xff0c 这两个模块都
  • ubuntu加入Windows的AD域(使用Samba和Winbind的方式)

    ubuntu加入Windows的AD域 Integrate Ubuntu 16 04 to AD as a Domain Member with Samba and Winbind Part 8 Step 1 Initial Configu
  • XTU 1262 Fish(优先队列+贪心)

    钓鱼 http 202 197 224 59 exam index php problem read id 1262 题目描述 小明很喜欢钓鱼 xff0c 现在有n个池塘可以钓鱼 xff0c 第i个池塘首次内能钓到ai条鱼 第i个池塘如果被
  • webpack开发调试模式devtool

    devtool 有7种模式 eval 文档上解释的很明白 xff0c 每个模块都封装到 eval 包裹起来 xff0c 并在后面添加 sourceURL source map 这是最原始的 source map 实现方式 xff0c 其实现
  • HDFS 集成 Kerberos

    本文主要记录 CDH Hadoop 集群上配置 HDFS 集成 Kerberos 的过程 xff0c 包括 Kerberos 的安装和 Hadoop 相关配置修改说明 注意 xff1a 下面第一 二部分内容 xff0c 摘抄自 Hadoop
  • html实现自动清理js、css文件的缓存

    方法如下 xff1a 1 手动清除浏览器缓存 xff1b 2 添加版本号 方法一 xff1a 可以通过js自动给html添加版本号 lt script type 61 34 text javascript 34 gt document wr
  • 虚拟机在nat模式下无法连接网络

    问题导入 在vmware下使用虚拟机由于某些原因设置了静态IP但是在后续的使用发现无法创建新的ssh连接 xff08 之前建立过连接并保存了密钥的仍可连接 xff09 xff0c 同时发现了主机网络可以正常ping通虚拟机的网络 xff0c
  • 74HC573芯片简介

    芯片缺口方向 为正 xff0c 然后左上往下排列 xff0c 最后一个是GND xff0c 然后 向右 xff0c 再向右上 xff0c 右上角为Vcc GND 和Vcc成对角线 xff0c 是为了防止发生短路 LE xff1a latch
  • c语言中返回值为char*的情况分析

    容易出错的地方在于 xff1a 指针作为返回值 xff0c 但是指针指向的内存单元在函数返回后 xff0c 内存单元释放了 xff0c 这样就导致了指针成了野指针了 xff01 xff01 xff01 这样会报错 xff0c 因为str数组
  • 网线水晶头接法分两种教程

    转载 xff1a https blog csdn net VickHUC article details 90081813 我们家里如果要用网线的话 xff0c 其实是可以自己接水晶头的 xff0c 当然你得有一个叫压线钳的工具 xff0c
  • STM32的定时器和DS18B20调试-第3季第8部分视频课程-朱有鹏-专题视频课程

    STM32的定时器和DS18B20调试 第3季第8部分视频课程 975人已学习 课程介绍 本课程是 朱有鹏老师单片机完全学习系列课程 第3季第8个课程 xff0c 本课程详细讲解STM32的定时器 xff0c 尤其是SYSTICK定时器和通
  • c语言/c++中指针的动态初始化及释放

    提醒 xff1a 使用指针最容易犯得错误是 xff0c 没有初始化就直接操作 xff01 xff01 xff01 1 指针的初始化 释放 1 xff09 指针指向一个内存单元 i c语言 xff1a char ch 61 char mall
  • c语言函数参数为指针的情况分析

    指针取 解引用 表示的是指针所指向内存单元中内容 xff1b 或者理解为该内存空间 指针传递其实也是一种值传递 xff0c 只不过传递的是地址值 xff0c 如果通过该地址取 解引用 xff0c 是可以改变形参指针的原值的 xff0c 但如
  • MATLAB快速傅里叶变换(fft)函数详解

    转载 xff1a https blog csdn net me4weizhen article details 53688848 定义 xff1a The 39 i 39 in the 39 Nth root of unity 39 是虚数
  • C++中substr()函数用法详解

    定义 substr 是C 43 43 语言函数 xff0c 主要功能是复制子字符串 xff0c 要求从指定位置开始 xff0c 并具有指定的长度 如果没有指定长度 Count或 Count 43 Off超出了源字符串的长度 xff0c 则子
  • 101、104规约解析

    转载 xff1a 电网101 104规约解析 xff08 Java xff09 张二狗和苗翠花的博客 CSDN博客 iec101 java 1 前言 最近在研究广东电网的101与104规约 xff0c 也就是DL T634 5101 200