Python 解析 DLT645 协议数据

DL/T 645是中国国家电网公司制定的一种用于电能表通信的协议,全称为《多功能电能表通信协议》。该协议主要用于电能表与数据采集终端(如集中器、抄表器等)之间的通信,以实现电能数据的采集、传输和管理。

主要特点

  1. 多功能性:支持多种电能参数的读取和设置,如电压、电流、功率、电能、功率因数等。
  2. 灵活性:支持多种通信方式,如RS-485、红外、无线等。
  3. 安全性:支持数据加密和身份验证,确保数据传输的安全性。
  4. 标准化:符合国家电网公司的标准,便于大规模部署和维护。

协议结构

DL/T 645协议的数据帧结构通常包括以下几个部分:

  1. 帧起始符:标识数据帧的开始,通常为0x68。
  2. 地址域:标识电能表的地址,通常为6字节。
  3. 控制码:标识命令类型,如读取数据、写入数据等。
  4. 数据域:包含具体的命令数据或返回的数据。
  5. 校验码:用于校验数据帧的完整性,通常为1字节。
  6. 帧结束符:标识数据帧的结束,通常为0x16。

常用命令

  • 读取数据:用于读取电能表的各种参数,如电压、电流、功率等。
  • 写入数据:用于设置电能表的参数,如时间、费率等。
  • 广播校时:用于同步电能表的时间。
  • 冻结命令:用于冻结电能表的当前数据,便于后续读取。

应用场景

DL/T 645协议广泛应用于智能电网、电力监控系统、远程抄表系统等领域。通过该协议,可以实现电能数据的实时采集、远程监控和自动化管理,提高电力系统的运行效率和管理水平。

数据报文格式:

数据报文解析相对来说并不复杂,所有的数据都是流式,直接按照顺序进行读取即可。不过里面数据的内容,并不需要在此进行数值转换(电力数据需要处理),基本读到什么内容就是什么内容。

例如原始数据:

message = b'hw8\x06(\x15Dh\x00\x02\x01\x1f(\x16'

解析数据可以通过下面的方法:

def process_645_data(message):
    print('message in hex=', message.hex())
    start_pos = message[0:1]
    # print('start_code = ', start_pos.hex())
    hid = message[1:7]
    # print(hid)
    # int_value = int.from_bytes(hid,byteorder='little')  # 默认使用大端模式
    # print(int_value)
    # int_value = int.from_bytes(hid,byteorder='big')  # 默认使用大端模式
    # print(int_value)
    print('hid = ', hid[::-1].hex())
    hid_hex = hid[::-1].hex()
    # print(hid.hex())
    data_pos = message[7:8]
    # print('data_pos = ', data_pos.hex())

    control_code = message[8:9]
    print('control_code = ', control_code.hex())
    data_length = message[9:10]
    print('data_length =', data_length.hex())
    data_lenth_int = int.from_bytes(data_length, byteorder='little')
    data = message[10:10 + data_lenth_int]
    print('data = ', data)
    crc_code = message[10 + data_lenth_int:11 + data_lenth_int]

    # crc_source = message[0:10 + data_lenth_int]

    # calced_crc = calc_crc(crc_source)
    # print('calced crc = ', calced_crc)

    print('crc_code = ', crc_code.hex())
    end_pos = message[11 + data_lenth_int:12 + data_lenth_int]
    # print('end_pos = ', end_pos.hex())

    return hid, hid_hex, control_code, data_lenth_int, crc_code, data

接收到的数据解析出来之后不需要再进行转换int.from_bytes(hid,byteorder=’little’) 不管是大端还是小端模式,转出来都是错的,直接将高低位倒序输出即可:hid[::-1].hex()

解析后的数据:

message in hex= 68773806281544680002011f2816
hid =  441528063877
control_code =  00
data_length = 02
data =  b'\x01\x1f'
crc_code =  28

对于数据上报的内容,例如电量,电报上报数据为下面的报文:

# 电量上报数据
data_msg = b'\x68\x77\x38\x06\x28\x15\x44\x68\x91\x08\x33\x33\x34\x33\x33\x33\x33\x33\x38\x16'

解析数据内容:

data_msg = b'\x68\x77\x38\x06\x28\x15\x44\x68\x91\x08\x33\x33\x34\x33\x33\x33\x33\x33\x38\x16'

hid, hid_hex, control_code, data_lenth_int, crc_code, data = process_654_data(data_msg)
print(control_code.hex())
print(data.hex())

data_type = data[0:4]
data_source = data[4:]
process_data_type = bytes(byte - 0x33 for byte in data_type)
print(process_data_type[::-1].hex())
process_data_data = bytes(byte - 0x33 for byte in data_source)
print(process_data_data[::-1].hex())
print(int(process_data_data[::-1].hex(), 16) / 100)

解析后的数据:

message in hex= 6877380628154468910833333433333333333816
hid =  441528063877
control_code =  91
data_length = 08
data =  b'33433333'
crc_code =  38
91
3333343333333333
00010000
00000000
0.0

crc 计算方法:

def calc_crc(src):
    sum = 0
    for i in range(len(src)):
        sum += src[i]
    crc = sum % 256
    return crc

 

数据解析处理参考:https://blog.csdn.net/m0_37651448/article/details/143100598

☆版权☆

* 网站名称:obaby@mars
* 网址:https://obaby.org.cn/
* 个性:https://oba.by/
* 本文标题: 《Python 解析 DLT645 协议数据》
* 本文链接:https://obaby.org.cn/2024/10/18421
* 短链接:https://oba.by/?p=18421
* 转载文章请标明文章来源,原文标题以及原文链接。请遵从 《署名-非商业性使用-相同方式共享 2.5 中国大陆 (CC BY-NC-SA 2.5 CN) 》许可协议。


You may also like

17 comments

  1.  Level 4
    Google Chrome 127 Google Chrome 127 GNU/Linux GNU/Linux cn中国–贵州–贵阳 移动

    把这个解析出来能干嘛 可以不用交电费吗 哈哈 研究一下😂

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn中国–山东–济南 联通

      哈哈哈,并不是,有个项目要通过这个计算电费,然后远程跳闸,😂

      1.  Level 4
        Google Chrome 127 Google Chrome 127 GNU/Linux GNU/Linux cn中国–贵州–贵阳 移动

        那能否弄一个计算好电费后 使用虚拟支持的方式来上报电费呢 (可能会被帽子叔叔请喝茶 哈哈哈哈) 主打一个能白嫖就白嫖 看能不能白嫖国家电网😂😂 (想法似乎有点危险)

        1. 公主 Queen 
          Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn中国–山东–济南 联通

          嫖不到的,这种需要计算电费的,基本都是代收,各种商业网点之类的。个人用户是直接交给国家电网的,也就不存在偷费的问题。
          如果不想交电费,可以把自己的线接到别人的电表上,或者越过电表,😂
          不过现在电表箱子都带锁,要想偷电还是比较麻烦的。

          1.  Level 4
            Google Chrome 127 Google Chrome 127 GNU/Linux GNU/Linux cn中国–贵州–贵阳 移动

            偷电改线搭电几乎也不太可能 因为好像每家每户的表上都有一个远程监控装置 如果电表上的灯突然不亮或者不闪了 要不了半个小时 供电局就会打电话来问 家里是不是停电了或者家里电表是不是跳闸了 再或者就直接上门了 几乎没有可能 哈哈哈哈 因为我家另一套房子在装修的时候我就试过 100%灵验 所以 还是老老实实缴费吧 😂

              1.  Level 4
                Google Chrome 127 Google Chrome 127 GNU/Linux GNU/Linux cn中国–贵州–贵阳 移动

                根据《中华人民共和国治安管理处罚法》第三十七条的规定,未经批准安装、使用电网或者安装、使用电网不符合安全规定的,可以处以拘留或罚款。此外,《中华人民共和国电力法》第三十二条明确指出,用户用电不得危害供电、用电安全和扰乱供电、用电秩序,对危害供电、用电安全和扰乱供电、用电秩序的行为,供电企业有权制止。第六十五条进一步规定,违反第三十二条规定,危害供电、用电安全或者扰乱供电、用电秩序的,由电力管理部门责令改正,给予警告;情节严重或者拒绝改正的,可以中止供电,可以并处五万元以下的罚款。
                私自将电线接搭在邻居家电表上 不仅违反了上述法律规定 还可能面临法律的处罚😂😂

      2.  Level 2
        Google Chrome 109 Google Chrome 109 Windows 10 Windows 10 cn中国–河北–保定 联通

        直接用插卡电表就可以吧,现在很多支持物联网的插卡电表,功率大的用互感器式的即可

        1. 公主 Queen 
          Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn中国–山东–青岛 联通

          这种一般是用来远程计费的。就是 4g 的电表。

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn中国–山东–济南 联通

      如果是通过自己的服务器计算就可以了,哈哈哈
      不管表上多少,电能上报始终不变就行了。

  2. Level 5
    Google Chrome 109 Google Chrome 109 Windows 10 Windows 10 cn中国–上海–上海 腾讯云

    控制电表翻转,劫持上报电量,直接空中充值电费

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn中国–山东–济南 联通

      代收费的确可以这么干,让用户免费用电

  3.  Level 5
    WebView 4 WebView 4 Android 12 Android 12 cn中国–广东–中山 电信

    工作代码吗?用python写的

    我拷贝你的代码拿去申请专利了哈 dance

    1. 公主 Queen 
      Google Chrome 126 Google Chrome 126 Mac OS X 10.15 Mac OS X 10.15 cn中国–山东–青岛 联通

      是哒,7878
      这些都没什么高级技术,随便用,嘎嘎

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注