前言:
首先跟大家分享一下这个需求的由来。有同行提出疑问,你是做IT方面工作的,怎么连抄电能表读数的活也揽过来了?
众所周知,当前已经是大数据的时代,数据采集是一切数据分析,数据挖掘的基石,当然要首先进行数据采集了。从IT的角度出发,技多不压身,能给公司的多做一些贡献不是更好嘛?
之前跟厂务严主管闲聊,公司内部在推行E4,重点关注水电气的消耗,还有CO2的排放。不聊不知道,一聊吓一跳。公司一个月的电费消耗小一百万出头,一年大概要到一千五百万。要是每年节省个5%出来,那就是50W+,这可不是个小数字哦。为了实现增效降本,他们做了一些监控,用了4G版的电能表数据采集,直接上传到云平台。数据是采集了,只是简单的看看曲线走势图,没有发挥出应有的数据价值。也就每个月看看用电量,至于深层次的用电量分析,受限于平台接口,始终无法实现大规模的自动化数据分析和潜在机会发掘,确实挺可惜的。
用技术为业务创造价值是IT的责任。基于目前的现状,我建议采用内网数据采集+内网的数据存储方案,再构建数据分析平台,基于历史的数据,建立能耗消耗模型,并进行电能消耗预测,看看所有的电能消耗是否在合理的区间范围内,想以此来判断这块电能表所负责的区域是否存在消耗浪费。
方案设计上没有问题了,说干就干。本文主要关注点是电能表读数采集实践。
思路:

- 德力西电表是现成的(支持DL/T 645-2007协议)
- 跟祁工聊了一下,他推荐了有人这个品牌,485转无线网络,目前看来效果不错,挺稳定,连接也便捷。
- 考虑到现场改造的难度,采用了无线解决方案,避免物理布线等问题,方便快速改造。
改造步骤:
- 调试有人USR-DR164
1.1关于这个设备,有人官方网站有详细的介绍。根据说明书,我选择了AP+STA模式,主要是为了方便后期调试。


通过设备自带AP功能,接入USR网络,进入管理界面,配置STA,配置完成SSID。串口设置方面,配置如截图:

这些参数需要根据设备要求一一对应,另外485连接也是A对A,B对B。
- 通过串口调试工具测试通讯。
打开工具,配置对应的IP地址,点击连接,显示就绪表示连接成功。

- 读取电表表号(地址)
-
2025-11-27 15:50:03.903\]# SEND HEX\>
-
2025-11-27 15:50:04.109\]# RECV HEX\>
-
2025-11-27 15:50:04.155\]# RECV HEX\>
根据返回值,可知83 11 60 20 20 62是这个表的地址。关于如何解析16位地址,可以参考DL/T 645-2007协议。
- 读取电能数据
返回有功总代码 68 83 11 60 20 20 62 68 11 04 33 33 34 33 48 16 #注意有功总不代表
2025-11-27 15:55:37.504\]# SEND HEX\> 68 83 11 60 20 20 62 68 11 04 33 33 34 33 48 16 \[2025-11-27 15:55:37.704\]# RECV HEX\> FE FE FE FE 68 83 11 60 20 20 62 68 91 08 33 33 \[2025-11-27 15:55:37.776\]# RECV HEX\> 34 33 53 4A A4 34 41 16 根据返回值可以得知53 4A A4 34 41为返回值。 5. 解析返回值 53 4A A4 34 41减33后反转数据 测试没有问题后,剩下的交给Python来实现自动化读取读数。 import socket import binascii s=socket.socket() host='192.168.1.137' port=8899 data=b"" all_line=\[
new_list=[]
new_list2=[]
tcp_client=socket.socket
send_data=b"\x68\x83\x11\x60\x20\x20\x62\x68\x11\x04\x33\x33\x34\x33\x48\x16"
encodings = ['utf-8', 'iso-8859-1', 'windows-1252']
def calc_result(hex_str1,hex_str2):
num1=int(hex_str1,16)
num2=int(hex_str2,16)
result=num1-num2
result_hex=hex(result)[2:].upper()
return result_hex
def get_e_value(sample):
source=''
for line in sample:
source+=line
source=source[8:]
s_len=int(len(source)/2)
print(s_len)
for i in range(0,s_len):
new_list.append(source[2*i:2*i+2])
print(source)
print(new_list)
indices=[i for i, item in enumerate(new_list) if item=='33']
print(indices[-1])
result=new_list[(indices[-1]+1):-2]
print(result)
for line in result:
new_list2.append(calc_result(line,'33'))
new_list2.reverse()
#print(new_list2)
e_value=float("".join(new_list2))/100
print("当前电表读数:",e_value)
try:
s.connect((host,port))
print("yes")
s.send(send_data)
s.settimeout(5.0)
for n in range(0,2): #因返回两行,二次读取。
response=s.recv(1024)
hex_str=binascii.hexlify(response).decode('utf-8')
all_line.append(hex_str)
get_e_value(all_line)
except Exception as e:
print("错误:",str(e))
执行代码,获得电能表读数,跟实际读数比较,结果一致。

- 创建计划任务,定时的读取电能表读数并保存到数据库中,接下来就是数据分析的事情啦。
通过这个实践,感觉收获颇分,大致总结了一下:
- 有人的这个DR164使用以及部署非常方便,非常使用老旧的工业设备数据采集,而且稳定性相当可靠。
- 解决了长期困扰我的一个问题,如何将老旧的设备进行联网管理,进而将IT的管理理念拓展到生产控制领域。通过这个实践,为以后的扩展铺平了道路。
- Python取数采用的是IP socket的方式,没有采用modbus tcp, 原因在于IP socket是一个通用的方法,通过支持的协议,可以使用到大量的工业设备上。
- 智能工厂,自动化是主流,IT应该扩展到这些领域,进行跨部门技术整合,碰撞出新的火花,485转网络给我提供了极大的信心,积极面对设备管理的挑战。
通过这个案例,也可以将IT监控管理体系扩展到广泛的生产设备领域。具体如何通过技术为业务创造价值,还需要多跟业务部门交流,多向他们学习,听听他们的心声,了解他们的痛点,进而进行优化,真正做到有的放矢。