from telnetlib import Telnet import serial DEBUG = True class MAXPacketFactory: def create_packet(rec: str): pkt_type = int(rec[7:9], 16) if pkt_type == 0: return MAXPairPingPacket.from_received(rec) elif pkt_type == 1: return MAXPairPongPacket.from_received(rec) elif pkt_type == 2: return MAXAckPacket.from_received(rec) elif pkt_type == 0xF1: return MAXWakeUpPacket.from_received(rec) elif pkt_type == 0xF0: return MAXResetPacket.from_received(rec) else: print("Unknown message type: {}".format(pkt_type)) return MAXPacket.from_received(rec) class MAXPacket: def __init__(self, length, message_counter: str, message_type: str, message_flag: str, sender_address: str, dest_address: str, group_id:str): self.length = length self.counter = message_counter self.type = message_type self.flag = message_flag self.sender_address = sender_address self.dest_address = dest_address self.group_id = group_id def from_received(rec: str): return MAXPacket(rec[1:3], rec[3:5], rec[5:7], rec[7:9], rec[9:15], rec[15:21], rec[21:23]) def gen_header(self): header_str = "{}{}{}{}{}{}".format(self.counter, self.flag, self.type, self.sender_address, self.dest_address, self.group_id) return header_str def to_string(self): return "MAXPacket: len={}, counter={}, flag={}, type={}, sender_addr={}, dest_addr={}, group_id={}".format( self.length, self.counter, self.flag, self.type, self.sender_address, self.dest_address, self.group_id ) class MAXPairPingPacket(MAXPacket): def from_received(rec: str): result = MAXPacket.from_received(rec) firmware_val = int(rec[23:25], 16) result.firmware_major = firmware_val // 16 result.firmware_minor = firmware_val % 16 result.device_type = rec[25:27] result.test_result = rec[27:29] result.serial = rec[29:-2] return result def __init__(self, length, message_counter: str, message_type: str, message_flag: str, sender_address: str, dest_address: str, group_id:str, firmware_major, firmware_minor, device_type, test_result, serial): MAXPacket.__init__(length, message_counter, message_type, message_flag, sender_address, dest_address, group_id) self.firmware_major = firmware_major self.firmware_minor = firmware_minor self.device_type = device_type self.test_result = test_result self.serial = serial def to_string(self): result = "{}\nMAXPairPingPacket: firmware_major={} firmware_minor={} device_type={} " \ "test_result={} serial={}".format(super().to_string(), self.firmware_major, self.firmware_minor, self.device_type, self.test_result, self.serial) return result class MAXPairPongPacket(MAXPacket): # def __init__(self, rec): # super().__init__(rec) def __init__(self, message_counter: str, message_flag: str, sender_address: str, dest_address: str, group_id:str): MAXPacket.__init__(message_counter, "01", message_flag, sender_address, dest_address, group_id) self.payload = "00" def serialize(self): header = self.gen_header() length = (len(header) + len(self.payload))/2 return "Zs{}{}{}".format(length, header, self.payload) class MAXAckPacket(MAXPacket): def __init__(self, rec): super().__init__(rec) class MAXWakeUpPacket(MAXPacket): def __init__(self, rec): super().__init__(rec) class MAXResetPacket(MAXPacket): def __init__(self, rec): super().__init__(rec) class CUL: def __init__(self): self.client: serial.Serial = None def connect(self, port): if self.client is None: self.client = serial.Serial(port, 38400, timeout=1) def disconnect(self): if self.client is not None: self.client.close() self.client = None def request(self, req): if self.client is not None: self.client.write(req.encode()) self.client.write(b"\n") if DEBUG: print(">>> {}".format(req)) else: print("Request while not connected!") def response(self): if self.client is not None: response = self.client.read(100).decode() if DEBUG: print("<<< {}".format(response)) return response else: print("Waiting for response while not connected!") return None def version_string(self): self.request("V") return self.response() def is_connected(self): return self.client is not None def set_moritz_mode(self, moritz_mode_enable): if moritz_mode_enable: self.request("Zr") #return self.response() else: self.request("Zx") class CUN: def __init__(self): self.client: Telnet = None def connect(self, host, ip): if self.client is None: self.client = Telnet(host, ip) def disconnect(self): if self.client is not None: self.client.close() self.client = None def version_string(self): self.request("V") return self.response() def request(self, req): if self.client is not None: self.client.write(req.encode()) self.client.write(b"\n") if DEBUG: print(">>> {}".format(req)) else: print("Request while not connected!") def response(self): if self.client is not None: response = self.client.read_some().decode() if DEBUG: print("<<< {}".format(response)) return response else: print("Waiting for response while not connected!") return None def set_moritz_mode(self, moritz_mode_enable): if moritz_mode_enable: self.request("Zr") #return self.response() else: self.request("Zx") def configure(self, ip, netmask, gateway, ): # ToDo: NYI pass def h_request(self): self.request("H?") return self.response() def send_moritz(self, packet: MAXPacket): # llnnccttssssssddddddpp... # ll - length # nn - msg counter # cc - control byte # tt - msg type # ss - sender address(3 byte) # dd - destination address(3 byte - 000000 for broadcast) # pp - payload... len_str = packet.length msg_counter_str = packet.ms control_byte_str = "00" message_type_str = "02" sender_addr_str = "000000" dest_addr_str = "000000" payload = "l:" self.request("Zs{}{}{}{}{}{}{}".format(packet.length, packet.message_counter, control_byte_str, message_type_str, sender_addr_str, dest_addr_str, payload)) #self.request("l:") return self.response()