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)
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)
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))