Adding Custom Fields to an ADIF File

I’m not much of a programmer. I’ll be the first to admit that. But, now and then, I manage to cobble together a useful script using the Python programming language to make short work of repetitive, tedious tasks. Here’s an example.

I described my process for logging contacts in a previous post. Part of that process is keeping track of where I was at the time and what rig I was using. My main log in N3FJP’s ACLog uses the other fields feature to implement the ADIF tags, MY_QTH and MY_RIG. Adding that information to ADIF files being imported into my main logging program was time-consuming.

I had been using ADIF Master to add these fields and populate them. I still highly recommend ADIF Master but I wanted to see if I could automate things using Python.

What I ended up with is a script that prompts me to enter my location and rig. If the ADIF file doesn’t already include a tag for TX_PWR, the script prompts me to enter my transmit power also. It then generates these new tags and inserts them in each record in the file. It takes me about 15 seconds to execute the script.

As I noted earlier, I’m no programmer. So, this code might not be the most elegant—or “Pythonic,” as they say—way to approach the problem. However, it does exactly what I needed.


Source Code

__author__ = "Craig LaBarge WB3GCK"
__email__ = "wb3gck at arrl.net"
__contact__ = "https://wb3gck.com/contact/"
__date__ = "5/03/2019"
__version__ = "v1.1.0"

# This script is used to add my custom tags to ADIFs exported from SKCCLogger or other programs.
# The script expects:
#     Files in ADIF located in the same working directory as the script
#     ADIF files must have a ".adi" or ".adif" extension.


import os
import sys


def listfiles():
    """This function finds all ADIF files in the working directory and prints out a listing with index
    numbers.  It returns a list of available ADIF files."""
    logs = []
    count = 1
    for filename in (os.listdir('.')):
        if '.adi' in filename:
            logs.append(filename)
            print(str(count) + ' - ' + filename)
            count = count + 1
    if not logs:   # Check for empty list; e.g., no PDFs found
        print('')
        print('Ooops! No ADIF files found!!  \nTerminating script...\n')
        sys.exit()
    else:
        print('')
        return logs


print('\n*** add_tags.py ' + __version__ + ' by WB3GCK ***\n')


# Prompt the user for the integer number corresponding to the desired message file.
# Check to make sure the input is within the proper range
good_file = False
file_choice = ''
file_list = listfiles()  # Get a list of ADIF files
file_in = ''
while not good_file:
    file_in = input('Enter the ADIF file number:  ')
    if not file_in.isdecimal():  # Check for non-numeric input
        print('Input must be a numeral!  Try again, Pal!')
        continue
    else:
        file_nr = int(file_in) - 1
    if file_nr < 0 or file_nr > (len(file_list) - 1):  # Check for out of range input
        print('Input out of range.  Better try that again, Bucko.')
    else:
        file_choice = file_list[file_nr]  # Sets the selected file name
        good_file = True

# Check the selected file for the presence of a TX_PWR tag
if ('TX_PWR' in open(file_choice).read()) or ('tx_pwr' in open(file_choice).read()):
    has_pwr = True
else:
    has_pwr = False

# Prompt user for the MY_QTH value
my_qth = input(r'Enter QTH:  ')
qth_tag = '<MY_QTH:' + str(len(my_qth)) + '>' + my_qth + ' '

# Prompt user for MY_RIG value
my_rig = input(r'Enter Rig:  ')
rig_tag = '<MY_RIG:' + str(len(my_rig)) + '>' + my_rig + ' '


# Prompt user for TX_PWR if there is no TX_PWR in the selected file
good_pwr = False
tx_pwr = ''
pwr_tag = ''
if not has_pwr:
    while not good_pwr:
        tx_pwr = input('Enter TX_PWR:  ')
        # Check for numerals and decimal points only
        try:
            val = float(tx_pwr)
            good_pwr = True
        except ValueError:
            print("Hey Bucko! Numerals and decimal points only!!")
    pwr_tag = '<TX_PWR:' + str(len(tx_pwr)) + '>' + tx_pwr + ' '

# Create the replacement tag
if not has_pwr:
    new_tags = qth_tag + rig_tag + pwr_tag + '<EOR>'
else:
    new_tags = qth_tag + rig_tag + '<EOR>'

# Modify the selected ADIF file
file = open(file_choice, 'r')
filedata = file.read()

# Replace the target string
if '<EOR>' in open(file_choice).read():
    filedata = filedata.replace('<EOR>', new_tags)
elif '<eor>' in open(file_choice).read():
    filedata = filedata.replace('<eor>', new_tags)
else:
    print('Are you sure this is a valid ADIF file?? \nTerminating script...')
    sys.exit()

file = open(file_choice, 'w')
file.write(filedata)

print('\nGreat success! ' + file_choice + ' modified.\n')

How to Run It

I run this script on a Windows machine, so this section is focused on that operating system. For Linux and Mac, you might need to do some research.

  • Make sure you have Python 3 installed on your computer. If not, you can get it for free at python.org.
  • Download the script file here and unzip it.
  • Place the ADIF file you want to modify in the same folder as the script file. 
  • Open a command window and navigate to the directory containing the script and ADIF file.
  • Start the script with the command: python add_tags.py. I use a Windows batch file to save having to save some typing. Depending on how Python is installed on your system, you might be able to just double-click the script file.
  • Following the prompts, enter the necessary information. That’s all there is to it.
Screenshot of the add_tag.py script running
Screenshot of the add_tag.py script running

Some Precautions

  • This script doesn’t check to see if you have already modified the ADIF file. If you have, you’ll end up with redundant fields in your ADIF file. Your logging program probably won’t like that.
  • Always keep a backup of your ADIF file or have an easy way to regenerate it. If you make a mistake in one of your inputs, just start over with another copy of the ADIF file.
  • I’ve only included a minimal amount of error checking in the script, so it’s far from bullet-proof. Double-check each input carefully before pressing <ENTER>.

Disclaimers

Of course, no article on software is complete without a disclaimer or two.

  • Use this script at your own risk. It works for me, but I make no guarantees that it will work for you.
  • I can’t offer any technical support or tailor it to your application.

So there you have it. If you find yourself having to routinely add fields to an ADIF file—maybe not, but you never know—feel free to modify this script to suit your needs. It should be easy to adapt it to add other ADIF tags.

If you want to dabble in Python programming, Google is your friend. There are tons of resources out there for learning Python.

73, Craig WB3GCK

Logging: Keeping Track of it All

Going all the way back to my Novice days in the mid-70s, I’ve always been a bit anal…  er… diligent, when it comes to logging contacts.  Years ago I started using logging software and that diligence persists.  Over the years, I’ve evolved to a logging process that I’m sure some would find overly complex.  It’s actually not that bad and it works well for me.

I use a variety of methods to capture QSO information.  Eventually, everything ends up in one central log.  From there, all QSOs are uploaded to Logbook of the World (LoTW).  The diagram below shows how everything ties together.

Overview of my logging process. In the end, all contacts end up in the Main Log.
Overview of my logging process. In the end, all contacts end up in the Main Log.

Here are the main components of my logging system:

ACLog.  I use this software by N3FJP for my main log.  All QSOs, no matter how they are made or logged wind up in here.  Because most of my HF operating is done while portable, I added a few custom fields to keep track of where I was (MY_QTH), what rig I was using (MY_RIG) and what power I was running (TX_PWR).  Everything in my main log gets uploaded to LoTW.  ACLog makes it very easy to do that.  For casual operating at home, I enter the contacts directly into ACLog.  Same goes for paper logs from portable operations with just a few contacts.  For larger batches of contacts, I might resort to other methods.

ADIF Master.  I use this great piece of freeware a lot.  It allows me to take an ADIF file and easily add in the custom fields I keep track of and do a quick bulk edit to populate the fields for all QSO records in the file.

Fast Log Entry (FLE).  I wrote about this software in an earlier post.  This came in handy last year for National Parks on the Air activations.  When I used paper logs for activations, FLE gave me a fast way to enter the QSO data and generate an ADIF file.

SKCC Logger.  I use AC2C’s SKCC Logger software to log all of my Straight Key Century Club contacts.  This software does automatic lookups from the SKCC member database when you enter a callsign.  It also helps keep track of award levels and generates award applications.  From SKCC Logger, I generate an ADIF file for further editing and importing into ACLog.

fldigi.  Every now and then I get on a digital mode kick.  Initially, I use fldigi’s internal log and export an ADIF file.  I haven’t worked JT65 or JT9 in a while but, when I do, I export an ADIF file from the WSJT-X software.

HamLog.  When I’m away camping for a few days, I use HamLog on Android cellphone to log my contacts.  If I have a cell connection, I can do QRZ.com lookups while logging a contact.  I export an ADIF file when I get home.  After, editing the ADIF and successfully importing it into ACLog, I go back to HamLog and clear out the log file so I’m ready for the next trip.

Contest Loggers.  When I use a specialized contest logging program for a contest… Well, you know the drill.  I export an ADIF file, edit in my custom fields, and ingest it into ACLog.

So, that’s it in a nutshell.  It probably sounds complicated but it has all become second nature to me.  I’m not suggesting that you do the same but, perhaps, some of the utilities and techniques will be useful to you.

I hope to see you somewhere down the log!

72, Craig WB3GCK

Fast Log Entry (FLE)

I recently discovered a very useful piece of software.  Fast Log Entry (FLE) is a small text editor that lets you quickly get your QSO information from paper logs onto your computer.  I originally installed FLE about a month ago but I didn’t immediately see its benefits.  After taking a closer look at it, I have now added into my logging utility “toolbox.”  FLE is a free download from DF3CB, although donations are welcomed.  It is a Windows application but it runs great on Linux under Wine.

Here’s a typical use case for me.  Quite often, I’m operating portable and logging my contacts in a small notebook.   If there’s a small number of contacts, I could just enter them into N3FJP’s ACLog, which I use for my main log.  However, entering into ACLog can be a little tedious if I have a significant number of contacts to deal with.  This is where FLE comes into play.

FLE provides a simple, keyboard-only, way of entering the information.  It uses a very simple format for the information.  To get started, you enter the date in the format YYYY-MM-DD.  Then, enter the band (e.g., 40m, 20m, etc.). Similarly, for the mode, you can just enter it (like “CW” or “SSB”).  See the screenshot below for an example.

Fast Log Entry (FLE) main screen
Fast Log Entry (FLE) main screen

You can now start entering your contacts.  Once you enter a contact at a particular time, you only need to enter the portion of the time that changed for the next contact.  For example, let’s say you worked a station at 1510 and another at 1511. After you enter the contact at 1511, you only have to enter “11” (i.e., just the minutes) for the next contact.  If you run a string of stations, you only need to note the time periodically in your paper log (say every 5 or 10 minutes).  FLE will interpolate the time for your contacts after you enter them if you like.  Also, there’s no need to worry about capitalization; FLE takes care of that.  You can enter RST (send and receive) information, or let it default to 599 or 59.  You can populate the “comments” field by enclosing the comment in angle brackets <>.  You can also add grid square information by prefacing it with a pound sign, like “#FN20.”

After you have finished entering your contacts, you can easily export an ADIF (Amateur Data Interchange Format) file for ingesting into your logging program.  FLE will also let you create a Cabrillo file for contest submissions.

My brief attempt at describing FLE probably doesn’t do it justice.  I recommend going to the author’s website to download a copy and taking it for a spin.  Be sure to check out the step-by-step instructions on the website.  Another great resource is a video by VK5PAS.  He gives a very thorough introduction to FLE and explains it much better that I can.  Although his video is targeted at the WorldWide Flora and Fauna program, it is a great tutorial on using FLE.

So, if you do a lot of portable operating with paper logs (think SOTA, NPOTA, IOTA, WWFF, etc.), take a look at FLE.

72, Craig WB3GCK

YFKtest Logger

I’m planning to take part in ARRL’s National Parks on the Air (NPOTA) event next year.  In fact, I plan to activate Valley Forge National Historic Park on New Year’s Day.  It will likely be cold so I plan to operate “stationary-mobile” from the cab of my pickup truck.  I suspect there will be a lot of “chaser” stations so I’m planning to use a computer for logging and sending CW.

I considered a couple of options.  One is to use N3FJP’s ACLog on my Windows laptop.  I use ACLog for my main log and I’m very comfortable with it.  The drawback is that my Windows laptop might be a bit large for the cramped cab of my little truck.  That led me to using my little Acer netbook computer, which runs Ubuntu Linux.

In my search for a contest-type logger for Linux, I tried several programs before stumbling across one called YFKtest.  YFKtest satisfied my three main requirements for a logging program:

  • It has to be simple to use with keyboard input only; I don’t want to have to use a mouse.
  • It needs to provide programmable CW messages and be able to key my transmitter.
  • It has to have the ability to export logs as ADIF files that I can import into my main log.

YFKtest main entry screen
YFKtest main entry screen

Fabian DJ1YFK is YFKtest’s original author while Bob Finch WY9A currently maintains the software.  Since it has been around for a while, the code base is stable.  YFKtest is a PERL program, so it runs under Linux.  It supports a large number of contests, including some QRP contests.  It generates CW over a serial or parallel interface, as well as via Winkey.  It works with the same serial interface that I use with the N3FJP software, so that’s a plus.  If you are so inclined, YFKtest will do rig control using the hamlib utilities. It also generates ADIF, Cabrillo and contest summary files.

YFKtest screenshot showing my custom CW messages
YFKtest screenshot showing my custom CW messages

Installation on Linux was straight-forward.  The user interface is a bit “old school,” compared to other logging software.  It was, however, easy to configure and use.   For NPOTA use, I took the “DXPED.def” definition file for DXpeditions and made a few minor tweaks to it. To give myself some peace of mind, I created a cron job in Linux that automatically backs up my log files to an SD memory card every 15 minutes.

YFKtest is hard coded for “599” or “59” signal reports.  There may be a way to accommodate honest signal reports, but I haven’t explored that yet.  Since LoTW doesn’t use signal reports, this is a non-issue for NPOTA logging.

Bob Finch’s support is top-notch.  During my initial testing with it, I reported a bug in the ADIF files.  In a day or two, Bob uploaded a fix.  You can’t complain about support like that.

So, I’m going to give YFKtest a shot for my New Year’s Day operation.  I’m anticipating a lot of NPOTA activity on the first day and that YFKtest will help me keep up with it!

For more information, visit the YFKtest website.

72, Craig WB3GCK