Sistem Log FT8 Automatik

Panduan langkah demi langkah menyambungkan WSJT-X ke Buku Log QSO Hamfinity.

Pemasangan Sistem "Live Bridge"

Sistem ini berfungsi dengan memantau fail log di komputer anda. Setiap kali anda klik "Log QSO" di perisian FT8, perisian kecil ini akan menghantarnya terus ke portal ini secara langsung. Ikuti 7 langkah mudah ini dengan teliti.

1 🐍 Pasang Perisian Python
  1. Pergi ke laman web rasmi: python.org/downloads
  2. Klik butang kuning besar (Download Python) untuk versi terkini Windows.
  3. Buka fail installer yang baru dimuat turun itu.
  4. ⚠️ SANGAT PENTING: Sebelum anda klik "Install Now", lihat di bahagian paling bawah tetingkap pemasangan. Anda MESTI tandakan (tick) kotak yang tertera "Add python.exe to PATH". Jika anda lupa langkah ini, sistem tidak akan berfungsi!
  5. Selepas ditanda, barulah klik Install Now dan tunggu ia selesai.
2 🌐 Pasang 'Requests' (Komunikator Internet)
  1. Tekan butang Windows di keyboard anda, taip perkataan cmd, dan tekan Enter. Satu tetingkap hitam (Command Prompt) akan terbuka.
  2. Salin (copy) arahan di bawah, tampal (paste) ke dalam tetingkap hitam tersebut, dan tekan Enter:
    pip install requests
  3. Sistem akan memuat turun beberapa fail secara automatik. Apabila tertera "Successfully installed", pangkah dan tutup tetingkap hitam itu.
3 📁 Cari Fail Log WSJT-X Anda
  1. Buka perisian WSJT-X (atau JTDX) seperti biasa.
  2. Di penjuru kiri sebelah atas, klik File kemudian pilih Open log directory.
  3. Satu folder komputer akan terbuka. Cari fail bernama wsjtx_log.adi di dalamnya.
  4. Klik pada ruang kosong di bar alamat (address bar) di bahagian paling atas folder tersebut. Tulisan di situ akan bertukar biru (contohnya: C:\Users\PC-Anda\AppData\Local\WSJT-X).
  5. Klik kanan tulisan biru itu dan pilih Copy. Simpan laluan (path) ini di dalam ingatan komputer anda (Clipboard).
4 📝 Cipta Fail Skrip Baru
  1. Buka aplikasi Notepad di komputer anda (Tekan Start, taip Notepad).
  2. Scroll ke bahagian paling bawah halaman panduan ini, salin (copy) keseluruhan KOD PYTHON yang berada di dalam kotak hitam.
  3. Tampal (paste) keseluruhan kod tersebut ke dalam Notepad anda. Jangan save dahulu, teruskan ke Langkah 5.
5 ⚙️ Kemas Kini Tetapan Skrip

Di bahagian atas kod dalam Notepad tadi, cari bahagian CONFIGURATION. Anda perlu ubah 3 perkara penting:

  1. API_KEY: Tukar kepada kata laluan rahsia (Sila mesej Admin untuk mendapatkan kod ini). Pastikan ia kekal di dalam tanda pengikat kata " ".
  2. MY_CALLSIGN: Gantikan "YOUR_CALLSIGN_HERE" dengan Callsign sebenar anda (Contoh: "9M8ZAL").
  3. WSJTX_LOG_PATH: Padam laluan lama, dan paste laluan (path) yang anda copy pada Langkah 3 tadi.
    ⚠️ PENTING: Anda MESTI menambah perkataan \wsjtx_log.adi di hujung laluan tersebut, dan biarkan huruf r kecil di hadapannya.
    Contoh: r"C:\Users\Ahmad\AppData\Local\WSJT-X\wsjtx_log.adi"
6 💾 Simpan Fail dengan Betul
  1. Di dalam Notepad, klik File -> Save As...
  2. Pilih lokasi penyimpanan di Desktop komputer anda.
  3. Pada bahagian Save as type (di bawah ruangan nama fail), tukar daripada "Text Documents (*.txt)" kepada "All Files (*.*)".
  4. Pada ruangan File name, taip nama ini dengan tepat: ft8_live_bridge.py
  5. Klik Save.
7 🚀 Lancarkan Sambungan Sistem!
  1. Buka semula tetingkap hitam Command Prompt (Tekan butang Windows, taip cmd, tekan Enter).
  2. Arahkan sistem untuk pergi ke Desktop dengan menaip arahan ini dan tekan Enter:
    cd Desktop
  3. Akhir sekali, hidupkan skrip anda dengan menaip arahan ini dan tekan Enter:
    python ft8_live_bridge.py

🎉 Tahniah, Anda Berjaya!

Selagi tetingkap hitam itu tertulis "QSO Hamfinity Live Bridge Started" dan dibiarkan terbuka, ia sedang bekerja. Cuba buat satu QSO di WSJT-X. Apabila anda tekan "Log QSO", tetingkap hitam itu akan memaparkan perkataan ✅ Success. Anda kini boleh menyemak buku log peribadi di portal QSO Hamfinity!

💻 Python Script Code

Salin semua baris kod di dalam kotak gelap ini dan tampal (paste) ke dalam fail ft8_live_bridge.py anda seperti yang diterangkan di Langkah 4.

import time
import os
import re
import requests

# ==========================================
# ⚙️ CONFIGURATION - CHANGE THESE 3 THINGS!
# ==========================================
# 1. The exact URL to your new API file
API_URL = "https://qso.hamfinity.com/dashboard/api_live_log.php"

# 2. Must match the secret key provided by the Admin
API_KEY = "QSOHamfinity_Live_Secret!" 

# 3. Your callsign (to tell the database whose logbook to put it in)
MY_CALLSIGN = "YOUR_CALLSIGN_HERE"

# The location of your WSJT-X ADIF log file. 
WSJTX_LOG_PATH = r"C:\Users\YOUR_PC_NAME\AppData\Local\WSJT-X\wsjtx_log.adi"
# ==========================================

def parse_adif_record(record_string):
    """Extracts data from a single ADIF string."""
    data = {}
    tags = ['call', 'band', 'mode', 'freq', 'rst_sent', 'rst_rcvd', 'qso_date', 'time_on', 'gridsquare']
    
    for tag in tags:
        match = re.search(rf'<{tag}:\d+[^>]*>([^<\s]+)', record_string, re.IGNORECASE)
        if match:
            data[tag] = match.group(1).strip()
    return data

def send_to_portal(qso_data):
    """Sends the extracted QSO to the QSO Hamfinity PHP API."""
    
    date_str = qso_data.get('qso_date', '')
    if len(date_str) == 8:
        date_str = f"{date_str[0:4]}-{date_str[4:6]}-{date_str[6:8]}"
        
    time_str = qso_data.get('time_on', '')
    if len(time_str) >= 4:
        time_str = f"{time_str[0:2]}:{time_str[2:4]}:{time_str[4:6] if len(time_str)>=6 else '00'}"

    payload = {
        'api_key': API_KEY,
        'owner_callsign': MY_CALLSIGN,
        'qso_call': qso_data.get('call', ''),
        'band': qso_data.get('band', ''),
        'mode': qso_data.get('mode', 'FT8'),
        'freq': qso_data.get('freq', ''),
        'grid': qso_data.get('gridsquare', ''),
        'rst_sent': qso_data.get('rst_sent', ''),
        'rst_rcvd': qso_data.get('rst_rcvd', ''),
        'qso_date': date_str,
        'qso_time': time_str
    }

    try:
        print(f"📡 Sending {payload['qso_call']} to QSO Hamfinity Portal...")
        response = requests.post(API_URL, data=payload)
        
        if response.status_code == 200:
            print(f"✅ Success: {response.text}\n")
        else:
            print(f"❌ Error {response.status_code}: {response.text}\n")
    except Exception as e:
        print(f"⚠️ Connection Failed: {e}\n")

def watch_log_file():
    """Watches the WSJT-X log file