Esempio n. 1
0
    def start(self):
        ADM.TRACKERS.add(self)
        self.db = pymysql.connect(**CONN)

        self.need_reply = 0
        self.imei = self.handle_imei()

        if not self.imei is None:
            logger.info(
                f'ADM{self.model} {self.imei} подключен [{self.addr[0]}:{self.addr[1]}]'
            )

            self.assign = get_configuration(self.NAME, self.imei, self.model)
            self.ign_v = get_ignition_v(self.imei)

            self.stop = False
            self.data = {}
            self.command_response = {}

            try:
                self.handle_packet()
            except Exception as e:
                self.close()
                logger.error('ADM ERROR {e}')
                raise e
Esempio n. 2
0
 def send_command(self, command):
     packet = ''
     # packet = add_ushort(packet, 0x4040)
     # packet = add_ubyte(packet, 0xFF)
     # packet = add_ushort(packet, len(command)+5)
     # packet = add_uint(packet, int(time()))
     # packet = add_ubyte(packet, 0x00)
     packet = add_str(packet, command)
     # crc16_pack = struct.unpack(f'{len(packet)//2}s', binascii.a2b_hex(packet.encode('ascii')))[0]
     # packet = add_ushort(packet, crc16(crc16_pack))
     # logger.info(f'[WialonCombine] командный пакет сформирован:\n{packet}\n')
     packet = pack(packet)
     try:
         self.sock.send(packet)
         logger.info(f'[WialonCombine]  команда {command} отправлена\n')
     except Exception as e:
         logger.error(
             f'[WialonCombine]  команда {command} не отправлена {str(e)}\n')
Esempio n. 3
0
    def run(self):
        logger.info(
            f"START {self.retranslator.protocol_name} {self.imei} [{self.ip}:{self.port}]"
        )
        while True:
            while self.socket == -1:
                self.socket = self.connect()
                sleep(Tracker.CONN_DELAY)

            while self.queue.qsize() == 0:
                self.fill_queue()

            row = self.queue.get()

            if row.get('reserve', None):
                row['imei'] = str(row['imei'])
                row['reserve'] = loads('{' + row['reserve'] + '}')
                row.update(row['reserve'])
                del (row['reserve'])

                if not row.get('sat_num', ''):
                    row.update({"sat_num": 0})

                row['lon'] = float(row['lon'])
                row['lat'] = float(row['lat'])

            sended, status = self.retranslator.send(self.send, row,
                                                    self.settings, self.ip,
                                                    int(self.port))

            if sended:
                msg = "Запись ОТПРАВЛЕНА\n"
            else:
                msg = "Запись НЕ ОТПРАВЛЕНА\n"

            msg += "Сервер".ljust(26, '-') + f"{self.ip}:" + f"{self.port}\n"
            msg += "Ретранслятор".ljust(
                26, '-') + f"{self.retranslator.protocol_name}\n"
            msg += "ID записи".ljust(26, '-') + f"{row['id']}\n"
            msg += "imei".ljust(26, '-') + f"{row['imei']}\n"
            msg += "Время точки".ljust(
                26, '-') + f"{datetime.fromtimestamp(row['datetime'])}\n"
            msg += "Статус отправки".ljust(26, '-') + f"{status}\n"
            msg += f"Записей для {self.imei}".ljust(
                30, '-') + f"{self.queue.qsize()}\n"

            if not sended:
                logger.error(msg)
            else:
                logger.info(msg)
                condition = f" WHERE `ip`='{self.ip}' AND `port`={self.port} AND `imei`={row['imei']}"
                query = f"SELECT * FROM `sent_id`" + condition
                with self.dbconn.cursor() as cursor:
                    cursor.execute(query)
                    if cursor.rowcount == 0:
                        query = f"INSERT INTO `sent_id` VALUES ({row['id']}, '{self.ip}', {self.port}, {row['imei']})"
                    else:
                        query = f"UPDATE `sent_id` SET `id`={row['id']}" + condition

                    cursor.execute(query)
                    self.dbconn.commit()

            self.queue.task_done()
Esempio n. 4
0
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
Esempio n. 5
0
    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')
Esempio n. 6
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)
Esempio n. 7
0
    def handle_io(self, packet):
        data = {}

        for extract_func in [
                extract_byte, extract_short, extract_int, extract_longlong
        ]:
            if self.codec == 8 or self.codec == 16:
                packet, count = extract_ubyte(packet)
            elif self.codec == 142:
                packet, count = extract_ushort(packet)
            else:
                logger.critical(f"Teltonika неизвестный кодек {self.codec}\n")
                raise ValueError('Unknown codec')

            iodata = {}
            for _ in range(count):
                if self.codec == 8:
                    packet, io_id = extract_ubyte(packet)

                elif self.codec == 142 or self.codec == 16:
                    packet, io_id = extract_ushort(packet)

                else:
                    logger.critical(
                        f"Teltonika неизвестный кодек {self.codec}\n")
                    raise ValueError('Unknown codec')

                packet, io_val = extract_func(packet)

                if str(io_id) not in self.decoder.keys():
                    logger.error(
                        f'[Teltonika] Неизвестный AVL IO ID {io_id}\n')

                else:
                    if str(io_id) in self.assign.keys():
                        ikey = self.assign[str(io_id)]
                        if '*' in ikey:
                            spl = ikey.split('*')
                            ikey, k = spl[0], spl[1]
                            io_val = round(io_val * float(k), 4)

                        iodata.update({ikey: io_val})

                    elif self.decoder[str(io_id)] in self.assign.keys():
                        ikey = self.assign[self.decoder[str(io_id)]]
                        if '*' in ikey:
                            spl = ikey.split('*')
                            ikey, k = spl[0], spl[1]
                            io_val = round(io_val * float(k), 4)

                        iodata.update({ikey: io_val})

                    else:
                        iodata.update({self.decoder[str(io_id)]: io_val})

            data.update(iodata)

        if self.codec == 142:
            packet, count = extract_ushort(packet)

            iodata = {}
            for _ in range(count):
                packet, io_id = extract_ushort(packet)
                packet, length = extract_ushort(packet)

                if length > 8:
                    packet, io_val = extract(packet, length)
                else:
                    packet, io_val = extract_x(packet, 'q', length)

                if str(io_id) not in self.decoder.keys():
                    logger.error(
                        f'[Teltonika] Неизвестный AVL IO ID {io_id}\n')

                else:
                    if str(io_id) in self.assign.keys():
                        ikey = self.assign[str(io_id)]
                        if '*' in ikey:
                            spl = ikey.split('*')
                            ikey, k = spl[0], spl[1]
                            io_val = round(io_val * float(k), 4)

                        iodata.update({ikey: io_val})

                    elif self.decoder[str(io_id)] in self.assign.keys():
                        ikey = self.assign[self.decoder[str(io_id)]]
                        if '*' in ikey:
                            spl = ikey.split('*')
                            ikey, k = spl[0], spl[1]
                            io_val = round(io_val * float(k), 4)

                        iodata.update({ikey: io_val})

                    else:
                        iodata.update({self.decoder[str(io_id)]: io_val})

            data.update(iodata)

        return packet, data
Esempio n. 8
0
    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} пакет не был принят")
Esempio n. 9
0
    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