def decodificar_hex(hex_string):
    TABELA_MCC = {724: "Brasil", 722: "Argentina", 334: "México", 310: "EUA"}
    TABELA_MNC_BR = {2: "TIM", 3: "TIM", 4: "TIM", 5: "Claro", 6: "Claro", 10: "Vivo", 11: "Vivo", 31: "Oi", 99: "Correios"}

    pacote = hex_string.replace(" ", "").upper()

    if pacote.startswith("7878"):
        offset = 0
        tamanho_bytes = 1
    elif pacote.startswith("7979"):
        offset = 2
        tamanho_bytes = 2
    else:
        return "Erro: Formato inválido. O pacote deve iniciar com 7878 ou 7979."

    try:
        idx_tamanho = 4
        hex_tamanho = pacote[idx_tamanho : idx_tamanho + (tamanho_bytes * 2)]
        tamanho_pacote = int(hex_tamanho, 16)
        
        idx_protocolo = 4 + (tamanho_bytes * 2)
        tipo_protocolo = pacote[idx_protocolo : idx_protocolo + 2]
        
        tamanho_payload = tamanho_pacote - 5 
        idx_payload = idx_protocolo + 2
        fim_payload = idx_payload + (tamanho_payload * 2)
        
        payload_hex = pacote[idx_payload : fim_payload]
        seq_hex = pacote[fim_payload : fim_payload + 4]
        sequencia = int(seq_hex, 16) if len(seq_hex) == 4 else "N/A"
        # ================================================================

        # ====================================================
        # LÓGICA PARA RESPOSTA DE COMANDO / VERSÃO (15)
        # ====================================================
        if tipo_protocolo == "15":
            # No protocolo 15, os primeiros bytes do payload costumam ser uma flag de erro/sucesso
            # e o restante é a mensagem em texto ASCII convertida para Hex.
            # Vamos converter o payload hex para texto ASCII removendo espaços/nulos
            try:
                # Converte o payload de hex para bytes e depois decodifica para string ASCII
                bytes_payload = bytes.fromhex(payload_hex)
                # O primeiro byte costuma indicar o idioma/status, o resto é a mensagem de texto
                # Vamos tentar traduzir tudo ignorando erros de caracteres estranhos
                texto_mensagem = bytes_payload[1:].decode('ascii', errors='ignore').strip('\x00')
            except:
                texto_mensagem = "Não foi possível converter para texto."

            return f"""
=========================================
  🔍 DECODIFICADOR J16 / GT06
=========================================
Pacote Hex : {pacote}
Protocolo  : {tipo_protocolo} (Resposta de Comando / Versão / Info)

--- 💬 MENSAGEM DO RASTREADOR ---
Texto Traduzido : {texto_mensagem}
Payload Bruto   : {payload_hex}

--- ⚙️ SISTEMA ---
ID Sequência    : {sequencia}
=========================================
"""

        # ====================================================
        # OUTROS PACOTES GENÉRICOS (01, 80, 94, etc)
        # ====================================================
        if tipo_protocolo not in ["13", "16", "22", "32"]:
            nomes_protocolos = {
                "01": "Login de Equipamento",
                "80": "Resposta de Comando",
                "94": "Transmissão de Dados (Sensores / Extra)",
                "0A": "Alerta / Informação do Terminal"
            }
            nome_prot = nomes_protocolos.get(tipo_protocolo, "Desconhecido")
            
            return f"""
=========================================
  🔍 DECODIFICADOR J16 / GT06
=========================================
Pacote Hex : {pacote}
Protocolo  : {tipo_protocolo} ({nome_prot})

Dados Úteis (Payload): {payload_hex}
ID de Sequência      : {sequencia}
=========================================
"""

        # ====================================================
        # LÓGICA PARA HEARTBEAT (13)
        # ====================================================
        if tipo_protocolo == "13":
            terminal_info = int(pacote[8+offset:10+offset], 16)
            voltagem = int(pacote[10+offset:12+offset], 16)
            sinal_gsm = int(pacote[12+offset:14+offset], 16)
            
            ignicao = "Ligada" if (terminal_info & 0x02) else "Desligada"
            energia = "Conectada" if (terminal_info & 0x04) else "Na Bateria Interna"
            corte = "Bloqueado" if (terminal_info & 0x80) else "Normal"
            alarme = "Acionado" if (terminal_info & 0x01) else "Nenhum"
            gps_fix = "Sinal Válido" if (terminal_info & 0x40) else "Sem Sinal GPS"
            
            niveis_bat = ["0%", "Muito Baixa", "Baixa", "Média-Baixa", "Média", "Alta", "100%"]
            bateria_texto = niveis_bat[voltagem] if voltagem <= 6 else f"Desc. ({voltagem})"
            niveis_gsm = ["Sem Sinal", "Fraco", "Regular", "Bom", "Excelente"]
            gsm_texto = niveis_gsm[sinal_gsm] if sinal_gsm <= 4 else f"Desc. ({sinal_gsm})"

            return f"""
=========================================
  🔍 DECODIFICADOR J16 / GT06
=========================================
Pacote Hex : {pacote}
Protocolo  : {tipo_protocolo} (Heartbeat / Status de Rotina)

--- 🔋 STATUS DO VEÍCULO ---
Ignição (ACC): {ignicao}
Bateria Rast.: {bateria_texto} (Nível {voltagem})
Energia Ext. : {energia}
Corte Comb.  : {corte}
Alarme Ativo : {alarme}
Sinal Celular: {gsm_texto} (Nível {sinal_gsm})
Módulo GPS   : {gps_fix}

--- ⚙️ SISTEMA ---
ID Sequência : {sequencia}
=========================================
"""

        # ====================================================
        # LÓGICA PARA LOCALIZAÇÃO (16, 22, 32)
        # ====================================================
        else:
            ano = int(pacote[8+offset:10+offset], 16) + 2000
            mes = int(pacote[10+offset:12+offset], 16)
            dia = int(pacote[12+offset:14+offset], 16)
            hora = int(pacote[14+offset:16+offset], 16)
            minuto = int(pacote[16+offset:18+offset], 16)
            segundo = int(pacote[18+offset:20+offset], 16)
            data_hora = f"{dia:02d}/{mes:02d}/{ano} {hora:02d}:{minuto:02d}:{segundo:02d} (UTC)"

            qtd_satelites = int(pacote[20+offset:22+offset], 16) & 0x0F

            lat_bruta = int(pacote[22+offset:30+offset], 16)
            lon_bruta = int(pacote[30+offset:38+offset], 16)
            latitude = lat_bruta / 1800000.0
            longitude = lon_bruta / 1800000.0

            velocidade = int(pacote[38+offset:40+offset], 16)
            
            curso_status = int(pacote[40+offset:44+offset], 16)
            curso_graus = curso_status & 0x03FF
            lat_hemisferio = "Norte" if (curso_status & 0x0400) else "Sul"
            lon_hemisferio = "Oeste" if (curso_status & 0x0800) else "Leste"
            gps_valido = "Válido" if (curso_status & 0x1000) else "Inválido"

            if lat_hemisferio == "Sul": latitude = -latitude
            if lon_hemisferio == "Oeste": longitude = -longitude

            texto_mcc, texto_mnc, lac, cell_id = "N/A", "N/A", "N/A", "N/A"
            
            if tipo_protocolo == "32":
                inicio_lbs = 44 + offset
                fim_lbs = 60 + offset
            else:
                tamanho_lbs = int(pacote[44+offset:46+offset], 16)
                inicio_lbs = 46 + offset
                fim_lbs = 46 + offset + (tamanho_lbs * 2)

            if len(pacote) >= fim_lbs:
                mcc = int(pacote[inicio_lbs:inicio_lbs+4], 16)
                mnc = int(pacote[inicio_lbs+4:inicio_lbs+6], 16)
                lac = int(pacote[inicio_lbs+6:inicio_lbs+10], 16)
                cell_id = int(pacote[inicio_lbs+10:inicio_lbs+16], 16)

                nome_pais = TABELA_MCC.get(mcc, "Desconhecido")
                texto_mcc = f"{mcc} ({nome_pais})"
                nome_operadora = TABELA_MNC_BR.get(mnc, "Desconhecida") if mcc == 724 else "Internacional"
                texto_mnc = f"{mnc} ({nome_operadora})"

            ignicao, energia, corte, alarme = "N/A", "N/A", "N/A", "N/A"
            bateria_texto, gsm_texto = "N/A", "N/A"
            
            if len(pacote) >= fim_lbs + 6:
                terminal_info = int(pacote[fim_lbs:fim_lbs+2], 16)
                voltagem = int(pacote[fim_lbs+2:fim_lbs+4], 16)
                sinal_gsm = int(pacote[fim_lbs+4:fim_lbs+6], 16)

                ignicao = "Ligada" if (terminal_info & 0x02) else "Desligada"
                energia = "Conectada" if (terminal_info & 0x04) else "Bateria Interna"
                corte = "Bloqueado" if (terminal_info & 0x80) else "Normal"
                alarme = "Acionado" if (terminal_info & 0x01) else "Nenhum"

                niveis_bat = ["0%", "Muito Baixa", "Baixa", "Média-Baixa", "Média", "Alta", "100%"]
                bateria_texto = niveis_bat[voltagem] if voltagem <= 6 else f"Desc. ({voltagem})"
                niveis_gsm = ["Sem Sinal", "Fraco", "Regular", "Bom", "Excelente"]
                gsm_texto = niveis_gsm[sinal_gsm] if sinal_gsm <= 4 else f"Desc. ({sinal_gsm})"

            mac_wifi = "N/A"
            if tipo_protocolo == "32" and len(pacote) >= 78 + offset:
                mac_bruto = pacote[66+offset:78+offset]
                mac_wifi = ':'.join(mac_bruto[i:i+2] for i in range(0, 12, 2))

            return f"""
=========================================
  🔍 DECODIFICADOR J16 / GT06
=========================================
Pacote Hex : {pacote}
Protocolo  : {tipo_protocolo} (Pacote de Localização)

--- 🌍 LOCALIZAÇÃO GPS ---
Data e Hora  : {data_hora}
Coordenadas  : {latitude:.6f}, {longitude:.6f}
Velocidade   : {velocidade} km/h
Direção      : {curso_graus}° ({lat_hemisferio}/{lon_hemisferio})
Satélites    : {qtd_satelites} conectados
Status GPS   : {gps_valido}

--- 🗼 REDE CELULAR E WI-FI ---
País (MCC)   : {texto_mcc}
Operad (MNC) : {texto_mnc}
LAC da Torre : {lac}
Cell ID      : {cell_id}
Rede Wi-Fi   : {mac_wifi}

--- 🔋 STATUS DO VEÍCULO ---
Ignição (ACC): {ignicao}
Bateria Rast.: {bateria_texto}
Energia Ext. : {energia}
Corte Comb.  : {corte}
Alarme Ativo : {alarme}
Sinal Celular: {gsm_texto}

--- ⚙️ SISTEMA ---
ID Sequência : {sequencia}
=========================================
"""

    except Exception as e:
        return f"Erro ao decodificar a mensagem: {str(e)}"

# Testando com a sua mensagem de resposta de comando (Protocolo 15)
mensagem = "78782D321A0810130309CA009CBA0903E2FCBC28991202D402960A08454B0A01000001A51DDC04E22900000D002BFBFF0D0A"
print(decodificar_hex(mensagem))

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: