Friday, November 13, 2026

KA9Q : tune call failed … with a timeout - Ongoing issue with KA9Q server connection

 Bayangkan begini. Tengah malam, saya menjenguk dashboard radiosonde_auto_rx seperti biasa. Sepatutnya saya nampak mesin kecil di rumah sedang sibuk mengimbas frekuensi, memburu isyarat radiosonde yang lalu di udara. Semuanya berjalan sendiri di atas Raspberry Pi, ditemani Airspy Mini dan KA9Q Radio. Saya cuma perlu memerhati.

Tetapi malam itu, yang menyambut saya bukan senarai hasil imbasan. Tiba-tiba muncul baris merah. Mula-mula “tune call failed … with a timeout”. Kemudian satu lagi: “Ongoing issue with KA9Q server connection”. Saya pandang skrin beberapa saat. Pelik. Bukankah servis KA9Q masih hidup?

Saya masuk ke terminal. Semak servis. Jawapannya ringkas: active. Semak Docker. Kontena radiosonde_auto_rx masih running. Kalau ikut pemeriksaan biasa, semuanya kelihatan normal. Tapi hakikatnya, radio saya tidak melakukan kerja yang sepatutnya. Pada saat itulah bermula satu malam yang lebih panjang daripada yang saya sangka.

Servis hidup, tapi ada sesuatu di dalamnya sudah stop

Saya cuba dapatkan data spektrum melalui arahan powers. Ada ketika ia terus menunggu sehingga timeout; ada masa fail CSV yang menjadi tempat hasil pengimbasan ditulis tinggal kosong, 0 bait. Ralat yang muncul pula bukan sekali dua. Return code 124—petanda proses itu melepasi had masa menunggu—mula menjadi pemandangan biasa.

Pada mulanya, saya tertanya-tanya sama ada Airspy Mini bermasalah, sambungan USB tidak stabil, atau KA9Q perlukan versi perisian yang lebih baharu. Saya semak log, sambungan kawalan, keadaan sistem dan versi alat KA9Q. Malah, saya cuba naik taraf komponen KA9Q kepada binaan yang lebih baharu. Hasilnya? Masalah yang sama masih datang semula.

Kemudian saya memeriksa sesuatu yang lebih dalam: thread bernama fft di dalam proses radiod. Thread itu wujud. Tetapi apabila saya bandingkan masa CPU dan rekod penjadualannya dalam dua pemeriksaan yang berjarak, nilainya langsung tidak bergerak. Pada skrin, servis masih active. Di dalamnya, kerja FFT seolah-olah membeku.

Itulah detik saya faham bahawa “proses hidup” dan “proses sedang bekerja” ialah dua perkara yang berbeza. Saya belum tahu punca dalaman sebenar FFT berhenti, tetapi sekurang-kurangnya sekarang saya tahu apa yang patut diperhatikan.

Satu restart, dan ok balik

Saya tidak mahu terus mencuba restart secara rambang. Jadi saya buat pemulihan secara tersusun: hentikan dahulu kontena auto_rx, restart servis radiod, kemudian hidupkan semula kontena. Saya mahu lihat sama ada perubahan itu benar-benar menghidupkan aliran pengimbasan.

docker stop radiosonde_auto_rx

sudo systemctl restart radiod@airspymini-autorx

docker start radiosonde_auto_rx

Harapan yang tak bertahan lama

Selepas restart, tanda-tandanya sangat melegakan. Thread FFT mula menggunakan masa CPU semula. Fail CSV yang tadinya kosong muncul dengan kandungan sekitar 61 ribu bait. Dashboard kembali menunjukkan puncak frekuensi yang berjaya dikesan. Saya ingat, mungkin inilah penyelesaiannya.

Tetapi beberapa minit kemudian, keadaan yang sama berulang. FFT terhenti, CSV kosong, dan timeout muncul lagi. Saya restart sekali lagi, ia pulih sekali lagi, kemudian terhenti sekali lagi. Seolah-olah sistem itu hanya mahu bekerjasama sekejap selepas dikejutkan.

Di sinilah saya menukar pendekatan. Kalau puncanya belum dapat dihapuskan, sekurang-kurangnya sistem ini mesti tahu sendiri bila ia benar-benar tersekat. Saya tidak mahu duduk menghadap skrin sepanjang hari hanya untuk menekan restart.

Daripada skrip pemerhati kepada Watchdog

Saya mula membina Watchdog. Versi awal, v0.5, masih terlalu sederhana. Ia boleh melihat tanda gangguan, tetapi belum cukup boleh dipercayai untuk membuat keputusan. Saya perbaiki pemeriksaan demi pemeriksaan. Dalam v0.6, saya mula meneliti keadaan FFT dan pengimbasan dengan lebih khusus. Namun masih ada keadaan tersangkut yang terlepas.

Akhirnya v0.7 menggunakan gabungan petunjuk: PID radiod, perubahan masa CPU thread FFT, umur kejayaan hasil CSV, proses powers, dan kehadiran decoder radiosonde. Yang penting, v0.7 hanya memerhati. Mod DRY RUN. Tiada restart automatik.

Pada malam 10 November 2026, bukti yang saya perlukan datang dengan cara yang agak menyakitkan hati. Saya buka log. Satu demi satu pemeriksaan memaparkan SUSPECTED_SCAN_STALL. Kaunter kegagalan bertambah: 95, 96, 97… hingga 111. Selama lebih empat jam, tiada kejayaan spektrum baharu direkodkan oleh Watchdog. radiod masih active, Docker masih running, tetapi FFT langsung tidak membuat kemajuan.

Saya tidak gembira kerana radio gagal. Tetapi saya lega kerana Watchdog akhirnya nampak kegagalan yang sama seperti yang saya lihat pada dashboard. Buat pertama kali, mesin itu tidak sekadar berkata “semuanya hidup”. Ia mula berkata, “ada sesuatu yang benar-benar tersekat”.

Ujian yang ajar saya supaya jangan cepat panik

Saya lakukan satu lagi restart terkawal. Kali ini PID radiod bertukar daripada 1174 kepada 31108. Thread FFT kembali bergerak dan kaunter kegagalan Watchdog kembali sifar. Kemudian saya jalankan ujian kecil: periksa saiz fail spektrum 12 kali, setiap lima saat.

Hasilnya menarik. Tujuh kali saya nampak CSV berisi data sekitar 61,368 hingga 61,370 bait. Lima kali pula ia kosong. Kalau saya melihat satu sampel kosong sahaja, mungkin saya akan salah sangka bahawa sistem rosak lagi. Rupanya proses powers memang boleh mengosongkan fail ketika memulakan kitaran pengimbasan baharu.

Saya belajar satu lagi perkara: satu bacaan 0 bait bukan hukuman mati untuk Scanner. Sistem pemantauan perlu membaca corak, bukan bertindak melulu terhadap satu angka.

Buat v0.8 

Daripada pengalaman itu saya bina Watchdog v0.8. Kali ini tujuannya bukan sekadar mengesan masalah, tetapi menyediakan pemulihan automatik yang mempunyai batas. Jika FFT tidak bergerak dan hasil spektrum sudah lama tidak berjaya, barulah ia mempertimbangkan tindakan. Itu pun selepas dua pemeriksaan gagal berturut-turut.

Saya tidak mahu pemulihan automatik memutuskan penerimaan ketika decoder sedang sibuk menyahkod radiosonde. Jadi decoder aktif menjadi syarat untuk tidak restart. Saya juga tetapkan cooldown 15 minit dan maksimum dua percubaan restart sejam, dengan rekod diagnostik sebelum tindakan dan semakan selepas pemulihan.

Saya pasang v0.8 pada Raspberry Pi. Pemeriksaan pertamanya memaparkan AWAITING_COMPARABLE_SAMPLE—memang munasabah kerana ia belum ada sampel kedua. Beberapa saat kemudian, decoder dikesan aktif, lalu keluar DECODER_ACTIVE_NO_RESTART. Selepas itu, FFT membuat kemajuan dan status bertukar kepada HEALTHY. Saya suka melihat log itu. Bukan kerana ia berwarna hijau, tetapi kerana keputusan-keputusannya masuk akal.

Akhirnya saya tukar mod daripada dry-run kepada auto. Pada 11:40:32 malam, log menunjukkan MODE: auto, FFT_PROGRESS: True, CSV_SIZE: 61368, STATUS: HEALTHY dan RESTARTS_LAST_HOUR: 0/2. Sistem tidak restart kerana memang tiada sebab untuk berbuat demikian.

Beberapa hari kemudian, saya kembali membuka dashboard

Saya perhatikan stesen itu selepas v0.8 diaktifkan. Kali ini, ralat yang sebelum itu berulang-ulang tidak muncul lagi dalam pemantauan saya. Saya boleh melihat keadaan sistem dengan lebih tenang, tanpa rasa perlu membuka terminal setiap beberapa minit.

Tetapi saya perlu jujur dalam catatan ini: saya belum dapat mengatakan bahawa v0.8 sudah membuktikan keupayaan restart automatik ketika insiden sebenar. Dalam log yang saya semak semasa mod auto aktif, keadaan sistem adalah HEALTHY dan tiada restart diperlukan. Saya juga belum menemui punca asas yang membuat FFT tersekat. Yang saya tahu, fungsi pemantauan sudah jauh lebih baik, prosedur pemulihan manual telah terbukti, dan mod pemulihan terkawal kini tersedia.

Dalam kerja-kerja sistem seperti ini, itu pun satu kemajuan besar. Kadang-kadang penyelesaian bukan datang sebagai satu arahan ajaib yang terus menghapuskan semua masalah. Kadang-kadang ia datang sebagai kefahaman yang perlahan-lahan dibina daripada log, nombor, kegagalan dan ujian yang berulang.

Apa yang malam tu ajar saya

Sebelum ini saya mungkin puas hati apabila systemctl memberitahu servis active. Sekarang saya tahu, itu baru permulaan. Untuk stesen SDR yang sepatutnya bekerja tanpa henti, kesihatan sebenar bukan sekadar proses masih wujud, tetapi sama ada isyarat diproses dan hasil benar-benar terhasil.

Saya juga sedar bahawa Watchdog yang baik bukanlah Watchdog yang paling cepat melakukan restart. Yang baik ialah yang cukup sabar untuk mengesahkan kegagalan, cukup berhati-hati untuk tidak mengganggu decoder, dan cukup berdisiplin untuk berhenti apabila had keselamatan dicapai.

Apabila saya melihat kembali baris merah “tune call failed” yang muncul pada malam itu, saya tidak lagi melihatnya sebagai gangguan semata-mata. Daripada satu sistem yang nampak hidup tetapi sebenarnya membisu, saya belajar membina sistem yang boleh memeriksa sama ada dirinya masih benar-benar bekerja.

Dan sejujurnya, itulah bahagian paling seronok dalam hobi radio dan Linux saya: bukan hanya saat semuanya berjalan lancar, tetapi saat saya akhirnya memahami mengapa ia pernah berhenti.

KA9Q : tune call failed … with a timeout - Ongoing issue with KA9Q server connection

  Bayangkan begini. Tengah malam, saya menjenguk dashboard radiosonde_auto_rx seperti biasa. Sepatutnya saya nampak mesin kecil di rumah sed...