A simple, ncurses-based amateur radio contact logger

#80 Look into updating DCO

~jeffpc commented on hlog todo

6 minutes ago

#94 watch: add missing new line in rig announcements

~jeffpc commented on hlog todo

15 minutes ago
hlog - A simple, ncurses-based amateur radio contact logger.

The main features are:

 - purely keyboard-based entry based on short commands (instead of
   navigating between fields)
 - uses a simple text-based storage (one file per log entry)
 - automatic continent, DXCC, ITU zone, and CQ zone lookup


To build hlog you must have:

  - gcc/clang or other C99 compiler with compatible arguments
  - libjeffpc (http://hg.31bits.net/libjeffpc/)
  - lua 5.3
  - gpsd 3.20
  - hamlib 3.3 or 4.3

Building and Installing

$ cmake . -DCMAKE_INSTALL_PREFIX=/prefix
$ make
$ make install

This will install the binaries under the specified prefix.

Note: If libjeffpc is not installed in a location that's part of the
compiler and linker search path, you'll have to give cmake a hint where to
find it.  You do this by defining these as necessary:

  - WITH_JEFFPC_LIB=x      - directory containing libjeffpc.so
  - WITH_JEFFPC_INCLUDES=x - directory containing jeffpc/jeffpc.h
  - WITH_JEFFPC=x          - same as setting WITH_JEFFPC_LIB=x/lib and

For example:

$ cmake . -DWITH_JEFFPC=/opt/jeffpc <...other cmake args...>


$ ./hlog <path to data directory>

The data directory must contain the following:

 - 'data' subdirectory
   - 'cty.csv' the country data
 - 'qso' subdirectory
 - 'tmp' subdirectory
 - 'config.lua' file


The config file (config.lua in the data directory) is a Lua script that
must evaluate to a table with default values and other knobs that affect

You can use the included init-data.sh script to generate a sample data

The possible config table keys are:

 fill_template      - function to set QSO field defaults
 qsoline            - array of tokens to use for qso-line

QSO Line

Logged QSOs are summarized as one line of text.  For example:

2020-11-07 13:49 W1ABC      14.2755    SSB    59  54    80W FN43

The exact information displayed is configurable via the qso-line config file
statement.  The qso-line statement includes a list of tokens representing
the various parts of the QSO entry.

The default value for qso-line is:

 qsoline = {
        "date", "time-hm", "station-call", "freq-mhz", "mode", "rsts",
        "rstr", "tx-power", "grid"

The possible tokens are (width in parentheses):

 band            - band name (5)
 county          - the contacted station's county name (10)
 date            - the start date of the QSO (10)
 freq-mhz        - the frequency in MHz (10)
 grid            - 8-character "dx" grid (8)
 grid4           - 4-character "dx" grid (4)
 grid6           - 6-character "dx" grid (6)
 grid8           - convenience alias for 'grid' (8)
 mode            - the mode (6)
 rstr            - the received RST (3)
 rsts            - the sent RST (3)
 seqr            - the received contest serial (4)
 seqs            - the sent contest serial (4)
 station-call    - the contacted station's callsign (10)
 time-hm         - the start time of the QSO in HH:MM format (5)
 time-hms        - the start time of the QSO in HH:MM:SS format (8)
 tx-power        - the local station's TX power (5)

Interactive Commands

Everything within hlog is controlled via simple case-insensitive text
commands.  In general, the commands fall into three categories:

 - contact management
 - local station information setting
 - contacted station information setting

The contact management commands start/end a contact.

The commands are:

 new              - start a new contact (saving the previous one), clears
                    everything except local station's call, grid square, and
 reset            - start a new contact (NOT saving the previous one),
                    clears everything except local station's call, grid
                    square, and power
 save             - save the contact, but continue editing it
 edit <uuid>      - load previously saved contact for viewing or editing
 tab new          - create a new tab
 tab close        - close the current tab
 tab <num>        - switch to the specified tab
 qrz              - open a new Firefox tab with contact's call on qrz.com
 ae7q             - open a new Firefox tab with contact's call on ae7q.com

The local station information commands allow the user to modify the
callsign, location, and power of the local station.  They all start with the
letter 'd' (as in "de").

The commands are:

 de <callsign>    - set local station & operator callsign (e.g., AC1JR)
 dg <grid>        - set local station's Maidenhead grid square (e.g., FN42)
 dpwr <watts>     - set local station's transmit power in Watts (e.g., 80)

Finally, the contacted station information commands allow the user to set
the fields associated with the other station.

The commands are:

 start now        - set the start date and time to the current time
 start <datetime> - set the start date and/or time
 startend now     - set the start & end date and time to the current time
 startend <datetime>
                  - set the start & end date and/or time
 end now          - set the end date and time to the current time
 end <datetime>   - set the end date and/or time
 pwr <watts>      - set contacted station's transmit power (e.g., 200)
 c <callsign>     - set contacted station's callsign (e.g., VO2MPR)
 f <MHz>          - set frequency (e.g., 14.2755)
 m <mode>         - set mode (e.g., SSB)
 rs <rst>         - set sent RST (e.g., 59)
 rr <rst>         - set received RST (e.g., 55)
 nm <name>        - set contacted station operator's name (e.g., Dave)
 qth <string>     - set contacted station's location (e.g., Point Armour)
 g <grid>         - set contacted station's Maidenhead grid square (e.g., GO11)
 country <country>- set contacted station's country (e.g., Canada)
 st <state>       - set contacted station's State/Province/etc. (e.g., NL)
 county <county>  - set contacted station's county
 cont <2 chars>   - set contacted station's continent
 dxcc <prefix>    - set contacted station's DXCC prefix
 itu <zone>       - set contacted station's ITU zone
 cqz <zone>       - set contacted station's CQ zone
 pota <refs>      - set contacted station's POTA references (comma separated)
 sota <refs>      - set contacted station's SOTA references (comma separated)
 wwff <refs>      - set contacted station's WWFF references (comma separated)
 cm <string>      - set (short) comment for this QSO
 seqs <num>       - set sent contest serial (e.g., 123)
 seqr <num>       - set received contest serial (e.g., 456)
 section <name>   - set received section abbreviation (e.g., EMA)

In general, the more common commands try to be short, so one is not forced
to type long strings in the middle of a contact.  As a result, many commands
are only one or two characters long.  While many of the commands are
intuitive, in most cases the field label underlines the characters of the
label that make up the command.

The "underline hint" exceptions are the local station commands, all of which
are prefixed with the letter 'd' (as in "de").  Note however, that the "set
local station's callsign" is "de" and not "dde".

For example, to set the contacted station's callsign (which is displayed
after the "Call:" label - with the letter C underlined), one would use the
'c' command followed by the other station's callsign.  For example:

 > c VO2MPR

This will populate the call field, look up the continent, DXCC prefix, 
the ITU and CQ zones, as well as calculate the distance and direction to the
contacted station based on the country data.


hlog assumes the following:

 - the rx and tx frequencies are the same
 - the local station callsign is the same as the local station operator's
 - the remote station callsign is the same as the remote station operator's

hlog also has the following shortcomings:

 - there is no way to display the contact end date even though it may be
   different from the start date
 - the distance calculation assume a spherical Earth with 6378.137 km radius
 - setting the contest sequence to 0 clears the field instead of using 0 as
   the value