コード例 #1
0
 def readDLMSPacket2(self, data, reply):
     if not data:
         return
     notify = GXReplyData()
     reply.error = 0
     eop = 0x7E
     #In network connection terminator is not used.
     if self.client.interfaceType == InterfaceType.WRAPPER and isinstance(
             self.media, GXNet):
         eop = None
     p = ReceiveParameters()
     p.eop = eop
     p.waitTime = self.waitTime
     if eop is None:
         p.Count = 8
     else:
         p.Count = 5
     self.media.eop = eop
     rd = GXByteBuffer()
     with self.media.getSynchronous():
         if not reply.isStreaming():
             self.writeTrace(
                 "TX: " + self.now() + "\t" + GXByteBuffer.hex(data),
                 TraceLevel.VERBOSE)
             print("TX: " + self.now() + "\t" + GXByteBuffer.hex(data))
             self.media.send(data)
         pos = 0
         try:
             while not self.client.getData(rd, reply, notify):
                 if notify.data.size != 0:
                     if not notify.isMoreData():
                         t = GXDLMSTranslator()
                         xml = t.dataToXml(notify.data)
                         print(xml)
                         notify.clear()
                     continue
                 elif not p.eop:
                     p.count = self.client.getFrameSize(rd)
                 while not self.media.receive(p):
                     pos += 1
                     if pos == 3:
                         raise TimeoutException(
                             "Failed to receive reply from the device in given time."
                         )
                     if rd.size == 0:
                         print("Data send failed.  Try to resend " +
                               str(pos) + "/3")
                         self.media.send(data, None)
                 rd.set(p.reply)
                 p.reply = None
         except Exception as e:
             self.writeTrace("RX: " + self.now() + "\t" + str(rd),
                             TraceLevel.ERROR)
             print("RX: " + self.now() + "\t" + str(rd))
             raise e
         self.writeTrace("RX: " + self.now() + "\t" + str(rd),
                         TraceLevel.VERBOSE)
         print("RX: " + self.now() + "\t" + str(rd))
         if reply.error != 0:
             raise GXDLMSException(reply.error)
コード例 #2
0
 def __init__(self) -> None:
     super().__init__()
     self.notify = GXReplyData()
     self.client = GXDLMSSecureClient()
     self.client.interfaceType = InterfaceType.PDU
     self.client.ciphering.security = Security.ENCRYPTION
     self.client.ciphering.blockCipherKey = GXCommon.hexToBytes(key_hex)
     self.translator = GXDLMSTranslator()
     self.reply = GXByteBuffer()
コード例 #3
0
 def readDLMSPacket(self, data, reply=None):
     if not reply:
         reply = GXReplyData()
     if isinstance(data, bytearray):
         self.readDLMSPacket2(data, reply)
     elif data:
         for it in data:
             reply.clear()
             self.readDLMSPacket2(it, reply)
コード例 #4
0
 def readList(self, list_):
     if list_:
         data = self.client.readList(list_)
         reply = GXReplyData()
         values = list()
         for it in data:
             self.readDataBlock(it, reply)
             values.extend(reply.value)
             reply.clear()
         if len(values) != len(list_):
             raise ValueError("Invalid reply. Read items count do not match.")
         self.client.updateValues(list_, values)
コード例 #5
0
 def close(self):
     if self.media and self.media._closed:
         print("DisconnectRequest")
         reply = GXReplyData()
         try:
             self.readDataBlock(self.client.releaseRequest(), reply)
         except Exception as e:
             pass
             #  All meters don't support release.
         reply.clear()
         self.readDLMSPacket(self.client.disconnectRequest(), reply)
         self.media.close()
コード例 #6
0
 def read(self, item, attributeIndex):
     data = self.client.read(item, attributeIndex)[0]
     reply = GXReplyData()
     self.readDataBlock(data, reply)
     if item.getDataType(attributeIndex) == DataType.NONE:
         item.setDataType(attributeIndex, reply.valueType)
     return self.client.updateValue(item, attributeIndex, reply.value)
コード例 #7
0
 def GetColumns(self, pg):
     entries = self.read(pg, 7)
     print("Reading Profile Generic: " + pg.logicalName() + " " + pg.description() + " entries:" + str(entries))
     reply = GXReplyData()
     data = self.client.read(pg.name, pg.objectType, 3)[0]
     self.readDataBlock(data, reply)
     self.client.updateValue(pg, 3, reply.value)
     return pg.captureObjects
コード例 #8
0
 def close(self):
     #pylint: disable=broad-except
     if self.media and self.media.isOpen():
         print("DisconnectRequest")
         reply = GXReplyData()
         try:
             #Release is call only for secured connections.
             #All meters are not supporting Release and it's causing
             #problems.
             if self.client.interfaceType == InterfaceType.WRAPPER or self.client.ciphering.security != Security.NONE:
                 self.readDataBlock(self.client.releaseRequest(), reply)
         except Exception:
             pass
             #  All meters don't support release.
         reply.clear()
         self.readDLMSPacket(self.client.disconnectRequest(), reply)
         self.media.close()
コード例 #9
0
 def getAssociationView(self):
     reply = GXReplyData()
     self.readDataBlock(self.client.getObjectsRequest(), reply)
     self.client.parseObjects(reply.data, True, False)
     #Access rights must read differently when short Name referencing is used.
     if not self.client.useLogicalNameReferencing:
         sn = self.client.objects.findBySN(0xFA00)
         if sn and sn.version > 0:
             read(sn, 3)
コード例 #10
0
 def readDLMSPacket2(self, data, reply):
     if data == None or len(data) == 0:
         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()
                     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)
コード例 #11
0
 def initializeConnection(self):
     print("Standard: " + str(self.client.standard))
     if self.client.ciphering.security != Security.NONE:
         print("Security: " + str(self.client.ciphering.security))
         print("System title: " + GXCommon.toHex(self.client.ciphering.systemTitle))
         print("Authentication key: " + GXCommon.toHex(self.client.ciphering.authenticationKey))
         print("Block cipher key: " + GXCommon.toHex(self.client.ciphering.blockCipherKey))
         if self.client.ciphering.dedicatedKey:
             print("Dedicated key: " + GXCommon.toHex(self.client.ciphering.dedicatedKey))
     self.updateFrameCounter()
     self.initializeOpticalHead()
     reply = GXReplyData()
     data = self.client.snrmRequest()
     if data:
         self.readDLMSPacket(data, reply)
         self.client.parseUAResponse(reply.data)
         size = self.client.limits.maxInfoTX + 40
         self.replyBuff = bytearray(size)
     reply.clear()
     self.readDataBlock(self.client.aarqRequest(), reply)
     self.client.parseAareResponse(reply.data)
     reply.clear()
     if self.client.authentication > Authentication.LOW:
         for it in self.client.getApplicationAssociationRequest():
             self.readDLMSPacket(it, reply)
         self.client.parseApplicationAssociationResponse(reply.data)
コード例 #12
0
 def updateFrameCounter(self):
     if self.invocationCounter and self.client.ciphering is not None and self.client.ciphering.security != Security.NONE:
         self.initializeOpticalHead()
         self.client.proposedConformance |= Conformance.GENERAL_PROTECTION
         add = self.client.clientAddress
         auth = self.client.authentication
         security = self.client.ciphering.security
         challenge = self.client.ctoSChallenge
         try:
             self.client.clientAddress = 16
             self.client.authentication = Authentication.NONE
             self.client.ciphering.security = Security.NONE
             reply = GXReplyData()
             data = self.client.snrmRequest()
             if data:
                 self.readDLMSPacket(data, reply)
                 self.client.parseUAResponse(reply.data)
                 size = self.client.limits.maxInfoTX + 40
                 self.replyBuff = bytearray(size)
             reply.clear()
             self.readDataBlock(self.client.aarqRequest(), reply)
             self.client.parseAareResponse(reply.data)
             reply.clear()
             d = GXDLMSData(self.invocationCounter)
             self.read(d, 2)
             self.client.ciphering.invocationCounter = 1 + d.value
             print("Invocation counter: " +
                   str(self.client.ciphering.invocationCounter))
             self.disconnect()
             #except Exception as ex:
         finally:
             self.client.clientAddress = add
             self.client.authentication = auth
             self.client.ciphering.security = security
             self.client.ctoSChallenge = challenge
コード例 #13
0
 def initializeConnection(self):
     print("Standard: " + str(self.client.standard))
     if self.client.ciphering.security != Security.NONE:
         print("Security: " + str(self.client.ciphering.security))
         print("System title: " +
               GXCommon.toHex(self.client.ciphering.systemTitle))
         print("Authentication key: " +
               GXCommon.toHex(self.client.ciphering.authenticationKey))
         print("Block cipher key: " +
               GXCommon.toHex(self.client.ciphering.blockCipherKey))
         if self.client.ciphering.dedicatedKey:
             print("Dedicated key: " +
                   GXCommon.toHex(self.client.ciphering.dedicatedKey))
     self.updateFrameCounter()
     self.initializeOpticalHead()
     reply = GXReplyData()
     data = self.client.snrmRequest()
     if data:
         self.readDLMSPacket(data, reply)
         self.client.parseUAResponse(reply.data)
         size = self.client.limits.maxInfoTX + 40
         self.replyBuff = bytearray(size)
     reply.clear()
     self.readDataBlock(self.client.aarqRequest(), reply)
     self.client.parseAareResponse(reply.data)
     reply.clear()
     if self.client.authentication > Authentication.LOW:
         try:
             for it in self.client.getApplicationAssociationRequest():
                 self.readDLMSPacket(it, reply)
             self.client.parseApplicationAssociationResponse(reply.data)
         except GXDLMSException as ex:
             #Invalid password.
             raise GXDLMSException(AssociationResult.PERMANENT_REJECTED,
                                   SourceDiagnostic.AUTHENTICATION_FAILURE)
コード例 #14
0
 def getAssociationView(self):
     reply = GXReplyData()
     self.readDataBlock(self.client.getObjectsRequest(), reply)
     self.client.parseObjects(reply.data, True, False)
     #Access rights must read differently when short Name referencing is used.
     if not self.client.useLogicalNameReferencing:
         sn = self.client.objects.findBySN(0xFA00)
         if sn and sn.version > 0:
             try:
                 self.read(sn, 3)
             except (GXDLMSException):
                 self.writeTrace(
                     "Access rights are not implemented for the meter.",
                     TraceLevel.INFO)
コード例 #15
0
    def getAssociationView(self):
        reply = GXReplyData()
        self.readDataBlock(self.client.getObjectsRequest(), reply)
        object_list = GXDLMSObjectCollection(self)
        object_list = self.client.parseObjects(reply.data, True)

        # print ('total objects: ' + str(len(object_list)))
        # print ('object list ' + str(object_list[0]))
        # print ('object list ' + str(object_list[1]))

        # register_class_obj = GXDLMSObjectCollection(self)
        # register_class_obj = object_list.getObjects(ObjectType.REGISTER)
        # print ('total register objects: ' + str(len(register_class_obj)))
        # for i in range(0, len(register_class_obj), 1):
        #     print(register_class_obj[i])

        return (object_list)
コード例 #16
0
 def initializeConnection(self):
     reply = GXReplyData()
     data = self.client.snrmRequest()
     if data:
         self.readDLMSPacket(data, reply)
         self.client.parseUAResponse(reply.data)
         size = self.client.limits.maxInfoTX + 40
         self.replyBuff = bytearray(size)
     reply.clear()
     self.readDataBlock(self.client.aarqRequest(), reply)
     self.client.parseAareResponse(reply.data)
     reply.clear()
     if self.client.authentication.value > Authentication.LOW.value:
         for it in self.client.getApplicationAssociationRequest():
             self.readDLMSPacket(it, reply)
         self.client.parseApplicationAssociationResponse(reply.data)
コード例 #17
0
    def onReceived(self, sender, e: ReceiveEventArgs):
        self.reply.set(e.data)
        data = GXReplyData()
        try:
            if not self.client.getData(self.reply, data, self.notify):
                self.reply.clear()
                #If all data is received.
                if self.notify.complete:
                    if not self.notify.isMoreData():
                        #Show received data as XML.
                        xml = self.translator.dataToXml(self.notify.data)
                        print(xml)
                        #Print received data.
                        self.printData(self.notify.value, 0)

                        #Example is sending list of push messages in first parameter.
                        if isinstance(self.notify.value, list):
                            objects = self.client.parsePushObjects(
                                self.notify.value[0])
                            #Remove first item because it's not needed anymore.
                            objects.pop(0)
                            Valueindex = 1
                            for obj, index in objects:
                                self.client.updateValue(
                                    obj, index, self.notify.value[Valueindex])
                                Valueindex += 1
                                #Print value
                                print(
                                    str(obj.objectType) + " " +
                                    obj.logicalName + " " + str(index) + ": " +
                                    str(obj.getValues()[index - 1]))
                        self.notify.clear()
                        self.reply.clear()
        except Exception as ex:
            print(ex)
            self.notify.clear()
            self.reply.clear()
コード例 #18
0
 def disconnect(self):
     #pylint: disable=broad-except
     if self.media and self.media.isOpen():
         print("DisconnectRequest")
         reply = GXReplyData()
         self.readDLMSPacket(self.client.disconnectRequest(), reply)
コード例 #19
0
ファイル: dlms_reader.py プロジェクト: sagor1155/dlms_python
 def send_keep_alive(self):
     reply = GXReplyData()
     data = self.settings.client.keepAlive()
     if data:
         self.reader.readDLMSPacket(data, reply)
         reply.clear()
コード例 #20
0
 def readByAccess(self, list_):
     if list_:
         reply = GXReplyData()
         data = self.client.accessRequest(None, list_)
         self.readDataBlock(data, reply)
         self.client.parseAccessResponse(list_, reply.data)
コード例 #21
0
 def getAssociationView(self):
     reply = GXReplyData()
     self.readDataBlock(self.client.getObjectsRequest(), reply)
     objects = self.client.parseObjects(reply.data, True)
     converter = GXDLMSConverter()
     converter.updateOBISCodeInformation(objects)
コード例 #22
0
 def readRowsByRange(self, pg, start, end):
     reply = GXReplyData()
     data = self.client.readRowsByRange(pg, start, end)
     self.readDataBlock(data, reply)
     return self.client.updateValue(pg, 2, reply.value)
コード例 #23
0
 def readRowsByEntry(self, pg, index, count):
     data = self.client.readRowsByEntry(pg, index, count)
     reply = GXReplyData()
     self.readDataBlock(data, reply)
     return self.client.updateValue(pg, 2, reply.value)
コード例 #24
0
    def initializeConnection(self):
        self.media.open()
        if self.iec and isinstance(self.media, GXSerial):
            p = ReceiveParameters()
            p.allData = False
            p.eop = '\n'
            p.waitTime = self.waitTime
            with self.media.getSynchronous():
                data = "/?!\r\n"
                self.writeTrace("TX: " + self.now() + "\t" + data,
                                TraceLevel.VERBOSE)
                self.media.send(data)
                if not self.media.receive(p):
                    raise Exception("Failed to received reply from the media.")

                self.writeTrace("RX: " + self.now() + "\t" + str(p.reply),
                                TraceLevel.VERBOSE)
                #If echo is used.
                replyStr = str(p.reply)
                if data == replyStr:
                    p.reply = None
                    if not self.media.receive(p):
                        raise Exception(
                            "Failed to received reply from the media.")
                    self.writeTrace("RX: " + self.now() + "\t" + str(p.reply),
                                    TraceLevel.VERBOSE)
                    replyStr = str(p.reply)

            if not replyStr or replyStr[0] != '/':
                raise Exception("Invalid responce : " + replyStr)
            baudrate = replyStr[4]
            if baudrate == '0':
                bitrate = 300
            elif baudrate == '1':
                bitrate = 600
            elif baudrate == '2':
                bitrate = 1200
            elif baudrate == '3':
                bitrate = 2400
            elif baudrate == '4':
                bitrate = 4800
            elif baudrate == '5':
                bitrate = 9600
            elif baudrate == '6':
                bitrate = 230400
            else:
                raise Exception("Unknown baud rate.")

            print("Bitrate is : " + bitrate)
            #Send ACK
            #Send Protocol control character
            controlCharacter = '2'.encode()
            #"2" HDLC protocol procedure (Mode E)
            #Mode control character
            #"2" //(HDLC protocol procedure) (Binary mode)
            modeControlCharacter = '2'.encode()
            #Set mode E.
            tmp = bytearray([
                0x06, controlCharacter, baudrate, modeControlCharacter, 13, 10
            ])
            p.reply = None
            with self.media.getSynchronous():
                self.media.send(tmp)
                self.writeTrace(
                    "TX: " + self.now() + "\t" + GXCommon.toHex(tmp),
                    TraceLevel.VERBOSE)
                p.waitTime = 200
                if self.media.receive(p):
                    self.writeTrace("RX: " + self.now() + "\t" + str(p.reply),
                                    TraceLevel.VERBOSE)
                self.media.close()
                self.media.dataBits = 8
                self.media.parity = Parity.NONE
                self.media.stopBits = StopBits.ONE
                self.media.baudRate = bitrate
                self.media.open()
                #This sleep make sure that all meters can be read.
                time.sleep(1000)

        reply = GXReplyData()
        data = self.client.snrmRequest()
        if data:
            self.readDLMSPacket(data, reply)
            self.client.parseUAResponse(reply.data)
            size = self.client.limits.maxInfoTX + 40
            self.replyBuff = bytearray(size)
        reply.clear()
        self.readDataBlock(self.client.aarqRequest(), reply)
        self.client.parseAareResponse(reply.data)
        reply.clear()
        if self.client.authentication > Authentication.LOW:
            for it in self.client.getApplicationAssociationRequest():
                self.readDLMSPacket(it, reply)
            self.client.parseApplicationAssociationResponse(reply.data)
コード例 #25
0
 def getAssociationView(self):
     reply = GXReplyData()
     self.readDataBlock(self.client.getObjectsRequest(), reply)
     self.client.parseObjects(reply.data, True)
コード例 #26
0
class MediaListener(IGXMediaListener):
    def __init__(self) -> None:
        super().__init__()
        self.notify = GXReplyData()
        self.client = GXDLMSSecureClient()
        self.client.interfaceType = InterfaceType.PDU
        self.client.ciphering.security = Security.ENCRYPTION
        self.client.ciphering.blockCipherKey = GXCommon.hexToBytes(key_hex)
        self.translator = GXDLMSTranslator()
        self.reply = GXByteBuffer()

    def onError(self, sender, ex):
        """
        Represents the method that will handle the error event of a Gurux
        component.
        sender :  The source of the event.
        ex : An Exception object that contains the event data.
        """
        print("Error has occured. " + str(ex))

    def onMediaStateChange(self, sender, e):
        """Media component sends notification, when its state changes.
        sender : The source of the event.
        e : Event arguments.
        """
        print("Media state changed. " + str(e))

    def onTrace(self, sender, e):
        """Called when the Media is sending or receiving data.
        sender : The source of the event.
        e : Event arguments.
        """
        print("trace:" + str(e))

    def onPropertyChanged(self, sender, e):
        """
        Event is raised when a property is changed on a component.
        sender : The source of the event.
        e : Event arguments.
        """
        print("Property {!r} has hanged.".format(str(e)))

    def onReceived(self, sender, e: ReceiveEventArgs):
        self.reply.set(e.data)
        data = GXReplyData()
        try:
            if not self.client.getData(self.reply, data, self.notify):
                self.reply.clear()
                #If all data is received.
                if self.notify.complete:
                    if not self.notify.isMoreData():
                        #Show received data as XML.
                        xml = self.translator.dataToXml(self.notify.data)
                        print(xml)
                        #Print received data.
                        self.printData(self.notify.value, 0)

                        #Example is sending list of push messages in first parameter.
                        if isinstance(self.notify.value, list):
                            objects = self.client.parsePushObjects(
                                self.notify.value[0])
                            #Remove first item because it's not needed anymore.
                            objects.pop(0)
                            Valueindex = 1
                            for obj, index in objects:
                                self.client.updateValue(
                                    obj, index, self.notify.value[Valueindex])
                                Valueindex += 1
                                #Print value
                                print(
                                    str(obj.objectType) + " " +
                                    obj.logicalName + " " + str(index) + ": " +
                                    str(obj.getValues()[index - 1]))
                        self.notify.clear()
                        self.reply.clear()
        except Exception as ex:
            print(ex)
            self.notify.clear()
            self.reply.clear()

    @classmethod
    def printData(cls, value, offset):
        sb = ' ' * 2 * offset
        if isinstance(value, list):
            print(sb + "{")
            offset = offset + 1
            #Print received data.
            for it in value:
                cls.printData(it, offset)
            print(sb + "}")
            offset = offset - 1
        elif isinstance(value, bytearray):
            #Print value.
            print(sb + GXCommon.toHex(value))
        else:
            #Print value.
            print(sb + str(value))