I have tried various programs for managing logbooks of Ham Radio contacts (QSOs). Many of them have an impressive set of features. They will fill in the current time, get the current frequency and mode from the radio, and even retrieve station details from the web. Some of them are integrated with Logbook of the World (LOTW) and do a great job of making that upload process painless. However, all of them seem to fall flat when it comes to manual entry of past QSOs. They typically:
- Pre-seed the current time down to second-level precision
- Show the QSO in a dialog rather than an editable grid
- Have no convenient way of applying changes in bulk.
- Support a staggering number of fields spread across multiple tabs.
For various reasons, many of my QSOs come from paper logs. Honestly, it’s a pain to keep wiping out the current time, clearing out the seconds field (I don’t write them down in that level of detail), and repeating the mode, date, and power. I would prefer a simple, editable grid.
Microsoft Excel is just that – an editable grid. I can easily drag ranges to fill in repeating information. I can skip from field to field with tab and QSO to QSO using enter. As an added bonus, it can be stored in a simple text file format (comma separated values or CSV). This can be easily read without the program and will likely still be usable 50 years in the future. This allows me to view these logs long after Excel is gone and easily repair corruption should it happen.
Converting CSV files to ADIF
Fortunately, all QSO matching services and logbook programs support a standard format called ADIF. While ADIF files are also plain-text, the format is arcane and inconvenient for manual entry. So, I produced a simple tool (csv2adif.py) that will convert CSV files to ADIF files. The following example:
Will convert the input file “mylog.csv” to “mylog.adif” and store it in the current working directory.
The input format is best demonstrated by example (sample). The CSV file will need to have a header row. This header should contain the ADIF field names of the fields. This allows the program to be somewhat adaptable and self-documenting. Additional fields can be added without modifying the program.
A few conversion are performed along the way. For all fields, leading and trailing spaces are stripped. The MODE and CALL fields are converted to upper case. Time fields are expected to be
HHMM and will be normalized such that low-order hours will have leading zeros. Dates are expected to be in the form of
DD-Mon-YY: a two digit day, two digit year, and month abbreviated as 3 English characters.
Any competent programmer can edit the script to change the expected input formats or add his/her own. I encourage you to do so.
Uploading ADIFs to LOTW
I have also provided a second tool that will sign and upload ADIF files to ARRL’s Logbook of the World service. The syntax of the command is:
This will invoke tsql.exe (which must be on your path) to sign the adif file. A .tq8 file of the same name will be produced in the same directory. Upon successful signing, this tq8 file will be immediately uploaded to LOTW using their web service.
You may also specify a signing location:
lotw_upload.py mylog.adif -l mylocation
Recently, LOTW has been having significant delays (hours to days) in processing uploaded data, so please be patient.
The scripts can be downloaded from simple-log-tools-0.91. Unzip them into a directory on your machine. You must have Python 2.7 or later installed on your machine. You must also have ARRL’s TrustedQSL software installed to perform LOTW uploads. Click here for more information on setting up LOTW.
I developed these scripts under Windows, but there is no reason why they shouldn’t work under Linux, Mac, or anything else that supports tsql and Python.
It is not my desire to compete with fully featured logging programs. If you want country statistics, dupe checking, and the like, you should be using one of those programs. However, you may still find csv2adif.py useful for importing manually entered data into these programs.
I hope some of you will find these scripts useful.
73 de AJ4MJ
Thanks for this. Now I can figure a way to just use it for contesting with EXCEL.
Thanks for this uncomplicated view of your tools. Just up me street
I would like to try the scripts but unfortunately the download page is missing.
Please reload the page and try again. I moved the binaries to a different location that should be accessible. It’s been a while since I wrote these, so hopefully they are still compatible with LOTW 🙂
Trying to get a spreadsheet csv file conveted. I named it mylog and set up a folder on my desktop with your python script and my log files. I downloaded python 2.7 and 3.6 to my iMac. I ran your script (from the same folder with the csv file) and got the error below:
Bobs-iMac:pythonpractice bobbennett$ ./csv2adif.py mylog.csv
./csv2adif.py: line 10: import: command not found
from: can’t read /var/mail/datetime
: command not found 12:
./csv2adif.py: line 14: syntax error near unexpected token `(‘
‘/csv2adif.py: line 14: `def strip(x): return x.strip()
Hi Bob. Try launching it using “python csv2adif.py mylog.csv” rather than ./csv2adif.py. I wrote this script on Windows which uses different logic than the Mac to figure out which interpreter to use. You also mentioned python 2 vs 3. It’s been a few years, but I’m pretty sure I wrote it against 2.
Bobs-iMac:pythonpractice bobbennett$ python csv2adif.py mylog.csv
Reading records from mylog.csv
Traceback (most recent call last):
File “csv2adif.py”, line 59, in
row[‘QSO_DATE’] = fixdate(row[‘QSO_DATE’])
File “csv2adif.py”, line 17, in fixdate
def fixdate(d): return datetime.strptime(d, ‘%d-%b-%y’).strftime(‘%Y%m%d’)
File “/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py”, line 332, in _strptime
ValueError: time data ‘2-Sept-2017’ does not match format ‘%d-%b-%y’
This is the problem I had with the other conversion program, it could not read the dates. Dont know what format the date should be in. I tried 9/2/17 and 2-Sep-17.
I think the “t” in Sept was the issue. 2-Sep-17 should be the right format.
If you need to, you can change the date format that my script is looking for. This might be easier than changing your data. To do this, alter the strptime(d, ‘%d-%b-%y’) in line 17 to something else. For example, if you wanted it to use a 4 digit year (2-Sep-2017), you can change it to strptime(d, ‘%d-%b-%Y’). See the table at https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior to see what all these placeholders mean. I’m not sure it will take “Sept”, so you may still need to change your CSV to “Sep”.