如何通过DLMS协议读取电表数据?

时间:2019-02-08 12:15:45

标签: python meter dlms

我尝试通过DLMS协议从电表读取数据,但是只有'/?!\r\n'不能工作,

我尝试读取(1-1.32.7.0 [电压])之类的数据,但无法将其用作 ASCII
然后我通过并行的 RS485从RS485记录数据 USB

所以下面显示的代码可以工作,但无论如何我都无法解码。

def readr():
    rcx2 = ser.readline()
    print(rcx2) 

def writex(data):
    ser.write(data.encode('raw_unicode_escape'))
    readr()

writex('\xa0\x07\x03!\x93\x0f\x01')writex('\xa0+\x03!\x10\xfb\xaf\xe6\xe6\x00`\x1d\xa1\t\x06\x07`\x85t\x05\x08\x01\x01\xbe\x10\x04\x0e\x01\x00\x00\x00\x06_\x1f\x04\x00\x00~\x1f\x04\xb0\xca\xea')
writex('\xa0\x19\x03!2o\xd8\xe6\xe6\x00\xc0\x01\xc1\x00\x01\x01\x00\x00\x00\x00\xff\x02\x00\xc3\xad')

writex('\xa0\x19\x03!T_\xde\xe6\xe6\x00\xc0\x01\xc1\x00\x03\x01\x01 \x07\x00\xff\x02\x00P\x1c')
writex('\xa0\x07\x03!q\x13\xc5')
writex('\xa0\x07\x03!S\x03\xc7')

2 个答案:

答案 0 :(得分:0)

在尝试读取属性之前,您需要执行许多步骤。您需要创建一个应用程序关联,并且在此之前,您需要将串行接口的模式更改为HDLC。您可能需要安全凭证才能创建具有对要读取的属性的访问权限的应用程序关联。您可以从the DLMS website获得蓝皮书和绿皮书的免费摘录,但是您可能需要IEC 62056标准或DLMS用户协会的完整绿皮书和蓝皮书才能建立通信。用户协会可通过用户协会网站为会员提供技术支持。

答案 1 :(得分:0)

有一个名为GuruX的优秀库,您可以将其用于抄表。

这是链接

Gurux Website

Github Project

一个示例请求就是这样。

首先,您需要安装该库:

pip install gurux-common
pip install gurux-serial
pip install gurux-net
pip install gurux-dlms

有关设置初始参数(例如服务器地址等)的信息,请参阅文档。

现在您可以读取数据了。

def readDLMSPacket2(self, data, reply):
if not data:
    return
notify = GXReplyData()
reply.error = 0
succeeded = False
rd = GXByteBuffer()
if not reply.isStreaming():
    self.writeTrace("TX: " + self.now() + "\t" + GXByteBuffer.hex(data), TraceLevel.VERBOSE)
    self.media.sendall(data)
msgPos = 0
count = 100
pos = 0
try:
    while not self.client.getData(rd, reply, notify):
        if notify.data.size != 0:
            if not notify.isMoreData():
                t = GXDLMSTranslator(TranslatorOutputType.SIMPLE_XML)
                xml = t.dataToXml(notify.data)
                print(xml)
                notify.clear()
                msgPos = rd.position
            continue
        rd.position = msgPos
        rd.set(self.media.recv(100))
    if pos == 3:
        raise ValueError("Failed to receive reply from the device in given time.")
    if pos != 0:
        print("Data send failed.  Try to resend " + str(pos) + "/3")
    ++pos
except Exception as e:
    self.writeTrace("RX: " + self.now() + "\t" + rd.__str__(), TraceLevel.ERROR)
    raise e
self.writeTrace("RX: " + self.now() + "\t" + rd.__str__(), TraceLevel.VERBOSE)
if reply.error != 0:
    raise GXDLMSException(reply.error)