{"id":42861466,"url":"https://github.com/mbridak/wfd_py_logger","last_synced_at":"2026-01-30T12:37:59.803Z","repository":{"id":40572207,"uuid":"178625655","full_name":"mbridak/wfd_py_logger","owner":"mbridak","description":"K6GTE Amateur Radio Winter Field Day Python Curses logger for Linux and maybe Mac","archived":false,"fork":false,"pushed_at":"2024-02-19T18:53:26.000Z","size":10480,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-25T07:29:56.202Z","etag":null,"topics":["amateur-radio","ham-radio","logger","logging","python","winter-field-day"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mbridak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://paypal.me/k6gte"]}},"created_at":"2019-03-31T00:29:15.000Z","updated_at":"2025-06-30T03:17:47.000Z","dependencies_parsed_at":"2023-02-15T12:30:48.469Z","dependency_job_id":null,"html_url":"https://github.com/mbridak/wfd_py_logger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mbridak/wfd_py_logger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbridak%2Fwfd_py_logger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbridak%2Fwfd_py_logger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbridak%2Fwfd_py_logger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbridak%2Fwfd_py_logger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mbridak","download_url":"https://codeload.github.com/mbridak/wfd_py_logger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mbridak%2Fwfd_py_logger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28912913,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T12:13:43.263Z","status":"ssl_error","status_checked_at":"2026-01-30T12:13:22.389Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amateur-radio","ham-radio","logger","logging","python","winter-field-day"],"created_at":"2026-01-30T12:37:59.728Z","updated_at":"2026-01-30T12:37:59.794Z","avatar_url":"https://github.com/mbridak.png","language":"Python","funding_links":["https://paypal.me/k6gte"],"categories":[],"sub_categories":[],"readme":"# K6GTE Winter Field Day logger (Curses)\n\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg?style=for-the-badge)](https://www.gnu.org/licenses/gpl-3.0) [![Python: 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg?logo=python\u0026style=for-the-badge)](https://www.python.org/downloads/)  [![Made With: Ancient Technology](https://img.shields.io/badge/Made%20with-Ancient%20technology-red?style=for-the-badge)][def] ![PyPI - Downloads](https://img.shields.io/pypi/dm/wfdcurses?label=PYPI-Downloads\u0026logo=pypi\u0026style=for-the-badge)\n\n![logo](https://github.com/mbridak/wfd_py_logger/raw/master/wfdcurses/data/k6gte.wfdcurses.svg)\n\n[Winter Field Day](https://www.winterfieldday.org/) is a once a year 24hr\nemergency preparidness event for radio amateurs (Hams). During the event, we try\nand make as many radio contacts with other Hams in a 24 hour period. Bonus\npoints are awarded for operating outside or using alternate power sources, such\nas battery/solar/wind. You can find out more about Winter Field Day by visiting\nthe [WFDA](https://winterfieldday.org/). You can find out more about amateur radio\nby visiting the [ARRL](https://www.arrl.org/).\n\nThe logger is written in Python 3, and uses the curses lib. It will work with Linux and Mac, but since the Windows curses lib is lacking it will not work properly in Windows.\n\nThe log is stored in an sqlite3 database file 'wfd.db'. If you need to wipe everything and start clean, just delete this file. The screen size expected by the program is an 80 x 24 character terminal.\n\nI decided to write this after the 2018 Winter Field Day when I couldn't find a simple Linux logger for the event. Just a simple logger with dup checking that could generate a cabrillo log for submission.\n\n![Alt text](https://github.com/mbridak/wfd_py_logger/raw/master/pics/logger.png)\n\n## TOC\n\n- [K6GTE Winter Field Day logger (Curses)](#k6gte-winter-field-day-logger-curses)\n  - [TOC](#toc)\n  - [Installation and running](#installation-and-running)\n  - [Recent Changes](#recent-changes)\n  - [Caveats](#caveats)\n  - [Initial Setup](#initial-setup)\n  - [Commands](#commands)\n  - [Logging](#logging)\n  - [Features](#features)\n    - [Radio Polling via rigctld or flrig](#radio-polling-via-rigctld-or-flrig)\n    - [QRZ, HamQTH, HamDB](#qrz-hamqth-hamdb)\n    - [Cloudlog](#cloudlog)\n    - [Bearing to contact](#bearing-to-contact)\n    - [Editing an existing contact](#editing-an-existing-contact)\n    - [Super Check Partial](#super-check-partial)\n    - [Section partial check](#section-partial-check)\n    - [DUP checking](#dup-checking)\n    - [Autofill](#autofill)\n    - [CW Keying and Macros](#cw-keying-and-macros)\n    - [cwdaemon use](#cwdaemon-use)\n  - [TODO](#todo)\n\n## Installation and running\n\nThe project is now on pypi. So now to install and run the package, you would:\n\n```bash\n#install it with\npip install wfdcurses\n\n#update with\npip install --upgrade wfdcurses\n\n#run it with\nwfdcurses\n```\n\n## Recent Changes\n\n- [24.2.19] Fixed deprecation changes to work on Python 3.9+\n- [24.1.27] Removed some deprecations.\n- [23.1.14] CAT, fixing flrig.\n- [23.1.14] Snazzy new app icon.\n- [22.12.28] Dropped BeautifulSoup and lxml, replaced with xmltodict.\n- [22.12.27] Digital modes are now DG not DI.\n- [22.12.18] You can now install via `pip install wfdcurses`\n- [22.12.16] The RAC sections have been updated for 2023\n- [22.11.12] Updated for 2023 WFD rules.\n- [22.6.29] Added CW macros\n\n## Caveats\n\nThis is a simple logger meant for a single op, it's not usable for clubs. There's no networking between logging machines etc.\n\n## Initial Setup\n\nAfter launching the program you may want to access the new Edit Settings screen by using the command listed in the next section. Here you can setup your call/class/section, CAT, callsign lookup, Cloudlog intigration, CW keyer.\n\n![Settings Screen](https://github.com/mbridak/wfd_py_logger/raw/master/pics/settings.png)\n\nNavigate the screen by pressing either `TAB` or `Shift-TAB`. Settings with brackets `[_]` are boolean. `[_]` means disabled and `[X]` is enabled. They can either be toggled with the `SPACE` key, or pressing either one of these `XxYy1` to enable, or one of these `Nn0` to disable it.\n\nAfter you make your changes, either press the `Enter` key to save your changes, or the `Esc` key to abort any changes and exit the screen.\n\n## Commands\n\nCommands start with a period character in the callsign field and are immediately followed by any information needed by the command.\n\n```text\n.H displays a short list of commands.\n.Q Quit the program.\n.S Access the settings screen\n.P# Sets the power level, .P5 will set the power to 5 watts.\n.MCW .MPH .MDI Sets the mode. CW Morse, PH Phone, DI Digital.\n.B# sets the band, .B40 for 40 meters.\n.D# Deletes log entry. .D26 will delete the log line starting with 026.\n.E# Edits log entry. .E26 will edit the log line starting with 026.\n.L Generate Cabrillo log file for submission.\n\n[esc] abort input, clear all fields.\n```\n\nAfter the command is entered press the ENTER key to execute it.\n\n## Logging\n\nOkay you've made a contact. Enter the call in the call field. As you type it in, it will do a super check partial (see below). Press TAB or SPACE to advance to the next field. Once the call is complete it will do a DUP check (see below). It will try and Autofill the next fields (see below). When entering the section, it will do a section partial check (see below). Press the ENTER key to submit the contact to the log. If it's a busted call or a dup, press the ESC key to clear all inputs and start again.\n\n## Features\n\n### Radio Polling via rigctld or flrig\n\nYou can enable/disable the use of rigctld or flrig in the settings screen. The flrig default port is 12345, and the default rigctld port is 4532.\n\nThe radio will be polled for band/mode updates automatically. There is an indicator at the bottom of the logging window to indicate polling status. Dim if no connection or timeout, and highlighted if all okay.\n\n![Alt text](https://github.com/mbridak/wfd_py_logger/raw/master/pics/rigctld.png)\n\n### QRZ, HamQTH, HamDB\n\nYou can enable callsign lookups by enabling them in the settings screen. If you choose either QRZ or HamQTH place you credentials for that service in the username and password fields provided.\n\n### Cloudlog\n\nYou can enable automatic logging to Cloudlog in the settings screen. Here you can enter your API key and URL to the service, along with a station ID if needed.\n\n### Bearing to contact\n\nOnce you put in your own call and choose a lookup provider, the program looks up your gridsquare. I did this because I didn't want to change the settings screen... I'm not kidding. After this, and after it looks up the grid for the other person, it'll show you the bearing and distance to the contact.  \n\n![screen clip of bearing](https://github.com/mbridak/wfd_py_logger/raw/master/pics/bearing.png)\n\n### Editing an existing contact\n\nUse the Up/Down arrow keys or PageUp/PageDown to scroll the contact into view. Your mouse scroll wheel may work as well. Double left click on the contact to edit, or use the '.E' command. Use the TAB or Up/Down arrow keys to move between fields. Backspace to erase and retype what you need.\nOnce done press the Enter key to save, or the Escape key to exit.\n\n![Alt text](https://github.com/mbridak/wfd_py_logger/raw/master/pics/editcontact.png)\n\n### Super Check Partial\n\nIf you type more than two characters in the callsign field the program will filter the input through a \"Super Check Partial\" routine and show you possible matches to known contesting call signs. Is this useful? Doubt it.\n\n![Alt text](https://github.com/mbridak/wfd_py_logger/raw/master/pics/scp.png)\n\n### Section partial check\n\nAs you type the section abbreviation you are presented with a list of all possible sections that start with what you have typed.\n\n![Alt text](https://github.com/mbridak/wfd_py_logger/raw/master/pics/sectioncheckpartial.png)\n\n### DUP checking\n\nOnce you type a complete callsign and press TAB or SPACE to advance to the next field. The callsign is checked against previous callsigns in your log. It will list any prior contact made showing the band and mode of the contact. If the band and mode are the same as the one you are currently using, the listing will be highlighted, the screen will flash, a bell will sound to alert you that this is a DUP. At this point you and the other OP can argue back and forth about who's wrong. In the end you'll put your big boy pants on and make a decision if you'll enter the call or not.\n\n![Alt text](https://github.com/mbridak/wfd_py_logger/raw/master/pics/dupe_check.png)\n\n### Autofill\n\nIf you have worked this person before on another band/mode the program will load the class and section used previously for this call so you will not have to enter this info again.\n\n### CW Keying and Macros\n\nYou can use either cwdaemon or PyWinkeyer as a keying interface. After you run the program and choose your keyer interface you will find a file called cwmacros.txt in the base directory that you launched the logger from. The file has 12 lines, corresponding to the 12 function keys on most keyboards. The format of the file is simple:\n\nF1|CQ|CQ WFD {MYCALL} {MYCALL} WFD\n\nThree fields separated by a `|` character. The first field is the function key to map. The second is the name of the macro being sent. Which in this case does not make a whole lot of sense, because you can't see the name... Just go with it. The last field is the macro to send.\n\nThere are 4 substitution macros provided: {MYCALL} {HISCALL} {MYCLASS} {MYSECT}\nThey send pretty much excatly what you think it should send.\n\nSo if your're running, you might want a macro like:\n\nF2|exchange|{HISCALL} {MYCLASS} {MYSECT}\n\nWho knows... Go wild. The world is your very limited, Oddly specific oyster.\n\n### cwdaemon use\n\nIf you use cwdaemon for your keyer, you can use the plus and minus on the keyboard to increase/decrease the sending speed by 1 wpm each time you press it. Pressing Escape aborts the sending.\n\n## TODO\n\n- Enter a contact at a specific time.\n\nLet me know if you think of something else.\n\n[def]: https://en.wikipedia.org/wiki/Curses_%28programming_library%29\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmbridak%2Fwfd_py_logger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmbridak%2Fwfd_py_logger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmbridak%2Fwfd_py_logger/lists"}