def handle_imei(self): try: packet = binascii.hexlify(self.sock.recv(1024)) logger.debug(f'[ADM{self.model}] пакет с imei: {packet}') packet, _ = extract_ushort(packet, '=') packet, _ = extract_ubyte(packet, '=') packet, _ = extract_ubyte(packet, '=') packet, imei = extract_str(packet, 15) if not imei.isdigit(): ADM.TRACKERS.remove(self) self.sock.close() self.db.close() self.stop = True return None packet, _ = extract_ubyte(packet, '=') packet, need_reply = extract_ubyte(packet, '=') self.need_reply = need_reply logger.debug( f'[ADM{self.model}] imei получен {imei}\nneed reply={need_reply}\n' ) # self.sock.send(struct.pack('!B', 1)) # logger.debug(f'[ADM] ответ на сообщение с imei отправлен\n') except Exception as e: self.close() raise e return imei.decode('ascii')
def fill_queue(self): with self.dbconn.cursor() as cursor: query = f"SELECT MAX(`id`) FROM `sent_id` WHERE `ip`='{self.ip}' AND `port`={self.port} AND `imei`={self.imei}" cursor.execute(query) last_id = cursor.fetchone()['MAX(`id`)'] if last_id == None: query = f"SELECT MAX(`id`) FROM `{RECORDS_TBL}`" cursor.execute(query) last_id = cursor.fetchone()['MAX(`id`)'] query = f"INSERT INTO `sent_id` VALUES ({last_id}, '{self.ip}', {self.port}, {self.imei})" cursor.execute(query) self.dbconn.commit() query = f"SELECT * FROM {RECORDS_TBL} WHERE `id`>{last_id} AND `imei`={self.imei}" cursor.execute(query) rows = cursor.fetchall() notemp = 0 for row in rows: if (row.get('lat', None) is not None) and (row['datetime'].timestamp() > 0): self.queue.put(row) notemp += 1 logger.debug( f'Найдено {notemp} записей для {self.imei} [{self.ip}:{self.port}]\n' )
def send_command(self, command): packet = '' packet = add_ubyte(packet, 0xf0) packet = add_ubyte(packet, 0x01) packet = add_str(packet, command) logger.debug( f'[ION] {self.imei} командный пакет сформирован:\n{packet}\n') packet = pack(packet) self.sock.send(packet) logger.debug(f'[ION] {self.imei} команда {command} отправлена\n')
def send_command(self, command): packet = '' packet = add_str(packet, command) packet = add_byte(packet, 0x0D) packet = add_byte(packet, 0x0A) logger.debug( f'[ADM{self.model}] {self.imei} командный пакет сформирован:\n{packet}\n' ) packet = pack(packet) self.sock.send(packet) logger.debug( f'[ADM{self.model}] {self.imei} команда {command} отправлена\n')
def connect(self): sock = socket.socket() sock.settimeout(0.1) sock.setblocking(0) try: sock.connect((self.ip, int(self.port))) return sock except Exception as e: logger.debug(f'Не удалось установить соединение ({e})' + f"\n{self.imei} [{self.ip}:{self.port}] ") return -1
def handle_header(self, packet): packet, _ = extract_short(packet, '>') packet, type = extract_byte(packet, '>') packet, self.pid = extract_ushort(packet, '>') packet, packet_length = self.get_extended_value_uint(packet) data = { k: v for k, v in locals().items() if k not in ('self', '_', 'packet', 'extra_len') } logger.debug(f'[WialonCombine] header data: {data} {self.pid}') return packet, data
def get_decoder(self, model): if model: decoder = load( open(self.BASE_PATH + f'avl_ids/{model.lower()}.json', 'r')) logger.debug( f"[Teltonika] для {self.imei} выбрана модель {model.lower()}\n" ) return decoder else: logger.critical( f"Teltonika для imei {self.imei} модель не найдена\n") raise ValueError('Unknown tracker')
def processing(fmt: dict, params: dict, endiannes=">"): """Обработчик Преобразует формат и параметры, вставляя нужные данные Пакует данные в байты fmt (dict): в виде param_name:struct_fmt params (dict): в виде param_name:value endiannes (str): byte-order """ params = Retranslator.in_correct_order(fmt, params) fmt, params = Retranslator.handler(''.join(fmt.values()), params) logger.debug(f"{fmt} {params}") block = Retranslator.pack_data(fmt, params, endiannes) return block
def handle_imei(self): try: packet = binascii.hexlify(self.sock.recv(34)) length = int(packet[:4], 16) packet = unpack_from_bytes(f'{length}s', packet[4:])[0] imei = packet.decode('ascii') logger.debug(f'[Teltonika] imei получен {imei}\n') self.sock.send(struct.pack('!B', 1)) logger.debug(f'[Teltonika] ответ на сообщение с imei отправлен\n') except Exception as e: self.sock.close() Teltonika.TRACKERS.remove(self) self.stop = True raise e return imei
def handle_command(self, packet): packet, _ = extract_ubyte(packet) packet, length = extract_uint(packet) if self.codec == 14: packet, imei = extract_str(packet, 8) length -= 8 elif self.codec == 13: packet, ts = extract(packet, 8) ts = int(b'0x' + timestamp, 16) ts /= 1000 packet, response = extract_str(packet, length) packet, _ = extract_ubyte(packet) packet, _ = extract_uint(packet) logger.debug(f'[Teltonika] пакет с ответом на команду распакован\n') return response.decode('ascii')
def handle_imei(self): try: packet = binascii.hexlify(self.sock.recv(1024)) logger.debug(f'[GalileoSky] пакет с imei: {packet}') tag = 0 while tag != 0x03: packet, tag = extract_ubyte(packet, '<') packet, imei = extract_str(packet, 15) # self.sock.send(struct.pack('!B', 1)) # logger.debug(f'[GalileoSky] ответ на сообщение с imei отправлен\n') except Exception as e: self.close() raise e return imei.decode('ascii')
def send(self, bmsg): try: msglen = len(bmsg) self.socket.send(bmsg) server_answer = self.socket.recv(1024) logger.debug( f'Пакет данных успешно отправлен (size {msglen} bytes)\n{hexlify(bmsg)}\n' + f'Ответ сервера (size {len(server_answer)} bytes)\n{hexlify(server_answer)}' + f"\n{self.imei} [{self.ip}:{self.port}] ") return hexlify(server_answer) except Exception as e: self.socket.close() self.socket = -1 logger.debug(f"Ошибка при отправке данных ({e})" + f"\n{self.imei} [{self.ip}:{self.port}] ") return -1
def handle_packet(self): if self.stop: self.stop = False while not self.stop: try: packet = binascii.hexlify(self.sock.recv(1024)) except Exception as e: self.close() break if len(packet) == 0: continue logger.debug(f'[GalileoSky] {self.imei} принят пакет {packet}') all_data = [] while len(packet) > 0: packet, data = self.data_main(packet) if packet is None: break
def handle_data(self, packet): all_data = [] codec_func = None #codec 8 if self.codec == 8: codec_func = self.codec_8 #codec 8 extended elif self.codec == 142: codec_func = self.codec_8 #codec 16 elif self.codec == 16: codec_func = self.codec_16 else: logger.critical(f"Teltonika неизвестный кодек {self.codec}") raise ValueError('Unknown codec') for rec in range(self.count): data = { 'imei': self.imei, 'ts': datetime.datetime.utcfromtimestamp(int(time())) } packet, codecdata = codec_func(packet) data.update(codecdata) if 'voltage' in data['iodata'].keys(): if self.ign_v is not None: if data['iodata']['voltage'] > self.ign_v: data['iodata']['ignition'] = 1 else: data['iodata']['ignition'] = 0 all_data.append(data) logger.debug(f"[Teltonika] #{len(all_data)}:\n{data}\n") logger.debug(f'[Teltonika] data:\n{all_data}\n') return all_data
def send_command(self, codec, command): result = '' codec = int(codec) if codec == 12: com_length = len(command) length = 8 + com_length elif codec == 14: com_length = 8 + len(command) length = 8 + com_length elif codec == 13: result = 'Сервер не может отправлять команду по кодеку 13!' return result else: result = f'Неизвестный кодек - {codec}' return result packet = '' packet = add_int(packet, 0) packet = add_uint(packet, length) packet = add_ubyte(packet, codec) packet = add_ubyte(packet, 1) packet = add_ubyte(packet, 5) packet = add_uint(packet, com_length) if codec == 14: packet = add_str(packet, self.imei.rjust(16, '0')) packet = add_str(packet, command) packet = add_ubyte(packet, 1) crc16_pack = struct.unpack( f'{len(packet[16:])//2}s', binascii.a2b_hex(packet[16:].encode('ascii')))[0] packet = add_uint(packet, crc16(crc16_pack)) logger.debug(f'[Teltonika] командный пакет сформирован:\n{packet}\n') packet = pack(packet) self.sock.send(packet) logger.debug(f'[Teltonika] команда отправлена\n')
def codec_8(self, packet): logger.debug( f'[Teltonika] CODEC {self.codec} AVL Data packet:\n{packet}\n') packet, timestamp = extract(packet, 8) timestamp = b'0x' + timestamp timestamp = int(timestamp, 16) timestamp /= 1000 packet, _ = extract_ubyte(packet) #priority packet, lon = extract_int(packet) lon /= 10000000 packet, lat = extract_int(packet) lat /= 10000000 packet, alt = extract_ushort(packet) packet, dr = extract_ushort(packet) dr = dr // 2 packet, sat_num = extract_ubyte(packet) packet, speed = extract_ushort(packet) dt = datetime.datetime.utcfromtimestamp(timestamp) data = { "datetime": dt, "lon": lon, "lat": lat, "alt": alt, "direction": dr, "sat_num": sat_num, "speed": speed } logger.debug(f'[Teltonika] AVL Data обработана:\n{data}\n') if self.codec == 8: packet, EventIO = extract_ubyte(packet) packet, NumOfIO = extract_ubyte(packet) elif self.codec == 142: packet, EventIO = extract_ushort(packet) packet, NumOfIO = extract_ushort(packet) elif self.codec == 16: packet, EventIO = extract_ushort(packet) packet, Generation_type = extract_ubyte(packet) packet, NumOfIO = extract_ubyte(packet) else: logger.critical(f"Teltonika неизвестный кодек {self.codec}\n") raise ValueError('Unknown codec') if EventIO == 385: packet, iodata = self.handle_beacon(packet) else: packet, iodata = self.handle_io(packet) data.update({"iodata": iodata}) logger.debug(f'[Teltonika] AVL IO Data обработана:\n{iodata}\n') return packet, data
def handle_data(self, packet): packet, timestamp = extract_uint(packet, '>') packet, count = extract_ubyte(packet, '>') logger.debug('timestamp ' + str(timestamp)) logger.debug('count ' + str(count)) packet_data = [] packet_reserve = {} for _ in range(count): logger.debug('packet ' + str(packet)) logger.debug('packet data ' + str(packet_data)) logger.debug('packet reserve ' + str(packet_reserve)) packet, type = extract_ubyte(packet, '>') logger.debug('type ' + str(type)) type = int(type) if type == 0: packet, count = self.get_extended_value_ushort(packet) for _ in range(count): logger.debug(f'custom {packet}') packet, name, value = self.handle_custom_param(packet) packet_reserve[name] = value elif type == 1: packet, data = self.handle_pos(packet) data['timestamp'] = timestamp packet_data.append(data) elif type == 2: packet, data = self.handle_io(packet) packet_reserve.update(data) elif type == 4: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, data = self.handle_lbs(packet) packet_reserve.update(data) elif type == 5: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, uid, value = self.handle_param(packet) packet_reserve[f'FUEL{uid}'] = value elif type == 6: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, uid, value = self.handle_param(packet) packet_reserve[f'TEMP{uid}'] = value elif type == 7: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, uid, value = self.handle_param(packet) packet_reserve[f'CAN{uid}'] = value elif type == 8: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, uid, value = self.handle_param(packet) packet_reserve[f'COUNTER{uid}'] = value elif type == 9: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, uid, value = self.handle_param(packet) packet_reserve[f'ADC{uid}'] = value elif type == 10: packet, count = extract_ubyte(packet, '>') for _ in range(count): packet, uid, value = self.handle_param(packet) packet_reserve[f'DRIVER{uid}'] = value elif type == 12: packet, msg = extract_str(packet, (len(packet) - 6) // 2, '!') msg = msg.decode() resp = {"action": "response", "result": msg} self.command_response = dumps(resp) packet_reserve[f'DRIVERMESSAGE'] = msg else: logger.error(f'[WialonCombine] idk') self.success = False break logger.debug( f'[WialonCombine] main data: {packet_data} [{packet_reserve}]') return packet, packet_data, packet_reserve
def handle_packet(self): if self.stop: self.stop = False while not self.stop: self.msg_type = 0 packet = binascii.hexlify(self.sock.recv(1024)) if len(packet) == 4: packet = binascii.hexlify(self.sock.recv(1024)) if len(packet) == 0: continue logger.debug( f'[ADM{self.model}] {self.imei} принят пакет {packet}') all_data = [] while len(packet) > 0: packet, data = self.data_main(packet) if packet is None: break logger.debug( f'[ADM{self.model}] {self.imei} основные данные обработаны\n{data}' ) logger.debug( f'[ADM{self.model}] {self.imei} статус пакета {data["typ"]}' ) bits = list(map(int, str(bin(data['typ']))[2:][::-1]))[2:] for n, bit in enumerate(bits): if bit: before = packet[:] packet, d = getattr(ADM, ADM.DATA_BLOCKS[n])(self, packet) logger.debug( f'[ADM{self.model}] {self.imei} блок {ADM.DATA_BLOCKS[n]}\nПакет до: {before}\nПакет после: {packet}\nДанные: {d}' ) data.update(d) data = self.rename_data(data) logger.debug( f'[ADM{self.model}] {self.imei} данные после переименования: {data}' ) data = self.prepare_geo(data) logger.debug( f'[ADM{self.model}] {self.imei} данные после обработки: {data}' ) all_data.append(data) if all_data: count = insert_geo(all_data) logger.info( f'ADM{self.model} {self.imei} принято {count}/{len(all_data)} записей' ) if self.need_reply == 1: pass elif self.need_reply == 2: self.sock.send(b'***' + str(count).encode('ascii') + b'*')
def prepare_data(self, header, main): header['posinfo'] = main data = self.assign_data(header) if self.model == 'v1': if data.get('IN_4'): if data['IN_4'] & 0x2: data['ignition'] = 1 else: data['ignition'] = 0 else: data['ignition'] = 0 else: if data.get('IN_4'): if data['IN_4'] & 0x1: data['ignition'] = 1 else: data['ignition'] = 0 if data['IN_4'] & 0x2: data['IN_0'] = 1 else: data['IN_0'] = 0 else: data['ignition'] = 0 for k in ('fuel_S', 'RPM', 'temp_4', 'param1', 'param2', 'param3', 'gsm', 'X', 'Y', 'Z', 'odom'): if data.get(k): data[k] = int(data[k]) if data.get('param1'): if data.get('param1') & 0x07: data['output_1'] = 1 else: data['output_1'] = 0 data['sat_num'] = data.get('param2', 0) + data.get('param3', 0) if data.get('fuel_used'): data['fuel_used'] = round(data['fuel_used'], 1) insert = 0 reserve = {} for k, v in data.items(): if k != 'posinfo': reserve.update({k: v}) reserve = str(reserve).replace("'", '"') reserve = reserve.replace(' ', '')[1:-1] if str(self.assign.get('sensor', 'true')).lower() == 'true': sensor = data.get('IN_0', 0) else: sensor = 0 if data.get('posinfo'): insert = 1 data = { "imei": self.imei, "lat": float('{:.6f}'.format(data['posinfo']['lat'])), "lon": float('{:.6f}'.format(data['posinfo']['lon'])), "datetime": datetime.utcfromtimestamp(data['posinfo']['timestamp']), "type": 0, "speed": data['posinfo']['speed'], "direction": data['posinfo']['direction'], "bat": 0, "fuel": 0, "ignition": data['ignition'], "sensor": sensor, "reserve": reserve, "ts": datetime.utcfromtimestamp(int(time())) } logger.debug(f'[WialonCombine] final data {data}') return data, insert
def data_main(self, packet): packet, _ = extract_ushort(packet, '=') packet, size = extract_ubyte(packet, '=') if size == 0x84: try: logger.debug( f'[ADM{self.model}] {self.imei} принят ответ на команду {packet}' ) result = self.handle_command(packet) except Exception as e: result = "Ошибка на сервере: " + str(e) resp = {"action": "response", "result": result} self.command_response = dumps(resp) logger.debug( f'[ADM{self.model}] {self.imei} ошибка распаковки ответа на команду\n{result}\n' ) logger.info(str(e)) else: resp = {"action": "response", "result": result} self.command_response = dumps(resp) logger.debug( f'[ADM{self.model}] {self.imei} ответ на команду принят\n{result}\n' ) return None, None packet, typ = extract_ubyte(packet, '=') packet, _ = extract_ubyte(packet, '=') packet, ID = extract_ushort(packet, '=') packet, status = extract_ushort(packet, '=') packet, lat = extract_float(packet, '<') packet, lon = extract_float(packet, '<') packet, direction = extract_ushort(packet, '=') packet, speed = extract_ushort(packet, '=') packet, ACC = extract_ubyte(packet, '=') packet, HEIGHT = extract_ushort(packet, '=') packet, HDOP = extract_ubyte(packet, '=') packet, SAT_N = extract_ubyte(packet, '=') packet, timestamp = extract_uint(packet, '=') packet, V_POWER = extract_ushort(packet, '=') packet, V_BATTERY = extract_ushort(packet, '=') direction /= 10 speed /= 10 ACC /= 10 if direction > 360: direction = 0 else: direction = (direction / 2) % 0xff SAT_N = (SAT_N & 0x0f) + ((SAT_N & 0xf0) >> 4) dt = datetime.datetime.utcfromtimestamp(timestamp) data = { key: value for key, value in locals().items() if key not in ['self', 'packet'] } return packet, data
def handle_packet(self): if self.stop: self.stop = False self.assign = None while not self.stop: try: packet = binascii.hexlify(self.sock.recv(2**17)) self.success = True except Exception: self.sock.close() self.db.close() self.stop = True self.success = False WialonCombine.TRACKERS.remove(self) logger.debug( f'[WialonCombine] отключен [{self.addr[0]}:{self.addr[1]}]' ) break logger.debug(f'[WialonCombine] получен пакет:\n{packet}\n') count = 0 command = False packet, packet_header = self.handle_header(packet) if packet_header['type'] == 0: try: self.handle_login(packet) except: logger.error(f'[WialonCombine] unknown packet\n') continue logger.debug(f'[WialonCombine] imei:\n{self.imei}\n') elif packet_header['type'] == 1: self.assign = get_configuration(self.NAME, self.imei, self.model) while len(packet) > 4: try: packet, packet_data, packet_reserve = self.handle_data( packet) except Exception as e: logger.debug( f'[WialonCombine] error parsing {packet} {str(e)}\n' ) break if packet_reserve.get('DRIVERMESSAGE'): command = True else: command = False if not packet_data and packet_reserve: packet_data.append({ "lat": 0, "lon": 0, "timestamp": int(time()), "speed": 0, "direction": 0, }) for data in packet_data: self.data, _ = self.prepare_data(packet_reserve, data) c = insert_geo([self.data]) count += 1 elif packet_header['type'] == 2: continue else: logger.debug( f"[WialonCombine] unknown type {packet} {packet_header['type']}\n" ) self.success = False if self.success: resp = '' resp = add_short(resp, 0x4040, '>') if not command: resp = add_byte(resp, 0x00, '>') else: resp = add_byte(resp, 255, '>') resp = add_ushort(resp, self.pid, '>') logger.debug( f'[WialonCombine] {self.imei} response to tracker:\n{resp}\n' ) resp = pack(resp) self.sock.send(resp) if count: logger.info( f"WialonCombine {self.imei} принято {count} записи") else: resp = '' resp = add_short(resp, 0x4040, '>') resp = add_byte(resp, 0x03, '>') resp = add_ushort(resp, self.pid, '>') resp = pack(resp) self.sock.send(resp) logger.warning( f"WialonCombine {self.imei} пакет не был принят")
async def handler(ws, path): while True: try: rec = await ws.recv() try: rec = loads(rec) except Exception as e: logger.error(f'WEBSOCKET неизвестный пакет: {rec} {e}\n') continue if rec['action']=='command': teltonika = Teltonika.Teltonika.get_tracker(rec['imei']) adm = ADM.ADM.get_tracker(rec['imei']) ion = ION.ION.get_tracker(rec['imei']) wialoncombine = WialonCombine.WialonCombine.get_tracker(rec['imei']) if any([teltonika, adm, ion, wialoncombine]): command_response = dumps({}) logger.debug(f"WEBSOCKET tracker {rec['imei']} found") if teltonika: teltonika.command_response = {} teltonika.send_command(int(rec['codec']), rec['command']) for _ in range(30): sleep(0.5) if teltonika.command_response!={}: command_response = teltonika.command_response break elif adm: adm.command_response = {} adm.send_command(rec['command']) for _ in range(30): sleep(0.5) if adm.command_response!={}: command_response = adm.command_response break elif ion: ion.command_response = {} ion.send_command(rec['command']) for _ in range(30): sleep(0.5) if ion.command_response!={}: command_response = ion.command_response break elif wialoncombine: wialoncombine.command_response = {} wialoncombine.send_command(rec['command']) for _ in range(30): sleep(0.5) if wialoncombine.command_response!={}: command_response = wialoncombine.command_response break if command_response!={}: logger.debug(f'WEBSOCKET command response\n{command_response}') try: await ws.send(command_response) except Exception as e: logger.error(f"WEBSOCKET ошибка при отправке ответа {e}") else: await ws.send(dumps({"action":"response", "result": "Время ожидания ответа истекло"})) else: await ws.send(dumps({"action":"response", "result": "Трекер не подключен"})) logger.info(f"WEBSOCKET {rec['imei']} не подключен") continue else: continue except Exception as e: raise e
def handle_packet(self): if self.stop: self.stop = False while not self.stop: try: packet = binascii.hexlify(self.sock.recv(4096)) except Exception as e: raise e if len(packet) == 0: continue logger.debug(f'[ION] получен пакет {packet}') packet, packet_type = extract_ubyte(packet) packets = None if packet_type == 0xe7 or packet_type == 0x83: packet, packets = extract_ubyte(packet) elif packet_type == 0xf0 or packet_type == 0xf1: result = self.handle_command(packet, packet_type) resp = {"action": "response", "result": result} self.command_response = dumps(resp) if not self.imei: first_time = True else: first_time = False packet, self.imei = ION.parse_imei(packet) if first_time: logger.info( f'ION {self.imei} подключен [{self.addr[0]}:{self.addr[1]}]' ) self.assign = get_configuration(self.NAME, self.imei) self.ign_v = get_ignition_v(self.imei) logger.debug(f'[ION] {self.imei} всего записей: {packets}') all_data = [] if packets: for i in range(packets): try: packet, data = ION.parse_data(packet) logger.debug(f'[ION] {self.imei} данные #{i} {data}') data = self.rename_data(data) logger.debug( f'[ION] {self.imei} данные после переименования: {data}' ) data = self.prepare_geo(data) logger.debug( f'[ION] {self.imei} данные после обработки: {data}' ) all_data.append(data) except Exception as e: logger.error( f'[ION] {self.imei} ошибка парсинга\n{str(e)}\nПакет {packet}' ) break else: while len(packet) > 0: try: packet, data = ION.parse_data(packet) logger.debug(f'[ION] {self.imei} данные #{i} {data}') data = self.rename_data(data) logger.debug( f'[ION] {self.imei} данные после переименования: {data}' ) data = self.prepare_geo(data) logger.debug( f'[ION] {self.imei} данные после обработки: {data}' ) all_data.append(data) except Exception as e: logger.error( f'[ION] {self.imei} ошибка парсинга\n{str(e)}\nПакет {packet}' ) break count = insert_geo(all_data) logger.info(f'ION {self.imei} принято {count}/{packets} записей') if packet_type == 0x82 or packet_type == 0x83: self.sock.send(b'0')
def handle_packet(self): while not self.stop: try: packet = binascii.hexlify(self.sock.recv(4096)) except Exception: self.sock.close() self.stop = True Teltonika.TRACKERS.remove(self) logger.debug( f'[Teltonika{self.model}] {self.imei} отключен [{self.addr[0]}:{self.addr[1]}]' ) break self.lock.acquire() if len(packet) < 8: if packet == b'\xff' or packet == b'' or packet == b'ff': continue else: logger.error(f'[Teltonika] непонятный пакет: {packet}') self.sock.close() self.stop = True Teltonika.TRACKERS.remove(self) logger.debug( f'[Teltonika{self.model}] {self.imei} отключен [{self.addr[0]}:{self.addr[1]}]' ) break logger.debug(f'[Teltonika] получен пакет:\n{packet}\n') try: packet, z = extract_int(packet) #preamble zero bytes assert z == 0, 'Not teltonika packet' packet, data_len = extract_uint(packet) packet, self.codec = extract_ubyte(packet) packet, self.count = extract_ubyte(packet) logger.debug( f'[Teltonika] codec={self.codec} rec_count={self.count}\n') except Exception as e: with open('tracker_receiver/src/logs/errors.log', 'a') as fd: fd.write(f'Ошибка в распаковке {packet}\n{e}\n') if self.codec in (8, 142, 16): self.data = self.handle_data(packet) self.data = prepare_geo(self.data) count = insert_geo(self.data) logger.info( f'Teltonika{self.model} {self.imei} принято {count}/{len(self.data)} записей' ) self.sock.send(struct.pack("!I", count)) elif self.codec in (12, 13, 14): result = self.handle_command(packet) resp = {"action": "response", "result": result} resp = dumps(resp) self.command_response = resp logger.debug( f'[Teltonika] ответ на команду принят\n{result}\n') else: logger.critical(f"Teltonika неизвестный кодек {self.codec}") raise ValueError('Unknown codec') self.lock.release() sleep(2) del (self)