Welcome to ft8decoder’s documentation!¶
Core Classes¶
- class ft8decoder.core.CQ(message: str, translated_message: str, caller: str, packet: Packet)[source]¶
Bases:
object
Represents a CQ (calling any station) message in amateur radio.
CQ messages are general calls broadcast to invite any station to respond, typically used to initiate new contacts or conversations.
- message¶
Original CQ message content
- Type:
str
- translated_message¶
Human-readable interpretation of the CQ
- Type:
str
- caller¶
Call sign of the station making the CQ call
- Type:
str
- packet¶
Packet object containing the raw signal data
- Type:
- caller: str¶
- message: str¶
- translated_message: str¶
- class ft8decoder.core.MessageTurn(turn: int, message: str, translated_message: str, packet: Packet | str, type: str)[source]¶
Bases:
object
Represents a single turn in a radio communication exchange.
- turn¶
Sequential turn number in the conversation
- Type:
int
- message¶
Original raw message content
- Type:
str
- translated_message¶
Human-readable or decoded version of the message
- Type:
str
- packet¶
Associated Packet object or string identifier
- Type:
ft8decoder.core.Packet | str
- type¶
Type of message turn (e.g., “CQ”, “response”, “73”)
- Type:
str
- message: str¶
- translated_message: str¶
- turn: int¶
- type: str¶
- class ft8decoder.core.Packet(snr: int, delta_time: float, frequency_offset: int, frequency: float, band: str, message: str, schema: int, program: str, time_captured: str, packet_type: int)[source]¶
Bases:
object
Represents a WSJT-X UDP packet containing signal and metadata information for each captured FT8 message.
- snr¶
Signal-to-noise ratio in decibels
- Type:
int
- delta_time¶
Time offset from expected timing in seconds
- Type:
float
- frequency_offset¶
Frequency offset from expected frequency in Hz
- Type:
int
- frequency¶
Actual received frequency in Hz or MHz
- Type:
float
- band¶
Radio frequency band (e.g., “20m”, “40m”, “2m”)
- Type:
str
- message¶
Raw message content from the packet
- Type:
str
- schema¶
Schema version or protocol identifier
- Type:
int
- program¶
Software/program that captured or processed the packet
- Type:
str
- time_captured¶
Timestamp when the packet was received (ISO format string)
- Type:
str
- packet_type¶
Numeric identifier for the type of packet
- Type:
int
- band: str¶
- delta_time: float¶
- frequency: float¶
- frequency_offset: int¶
- message: str¶
- packet_type: int¶
- program: str¶
- schema: int¶
- snr: int¶
- time_captured: str¶
Parser Module¶
- class ft8decoder.parser.WsjtxParser(dial_frequency: float, log_level=20)[source]¶
Bases:
object
A UDP packet parser for WSJT-X FT8 messages.
This class listens for UDP packets from WSJT-X software, parses the binary packet data to extract FT8 message information, and queues the parsed packets for processing by a MessageProcessor.
The parser handles WSJT-X’s binary protocol format and converts frequency offsets to absolute frequencies while determining the amateur radio band based on the calculated frequency.
- logger¶
Logger instance for this class
- Type:
logging.Logger
- packet_queue¶
Thread-safe queue for storing parsed packets
- Type:
queue.Queue
- dial_frequency¶
Base dial frequency in MHz from WSJT-X
- Type:
float
Example
>>> parser = WsjtxParser(dial_frequency=14.074) >>> processor = MessageProcessor() >>> parser.start_listening('127.0.0.1', 2237, processor)
- determine_band(frequency: float)[source]¶
Determine amateur radio band from frequency.
Maps the calculated frequency to the appropriate amateur radio band designation based on common FT8 frequencies. Uses a tolerance of ±15 kHz to account for frequency variations.
- Parameters:
frequency (float) – Frequency in MHz to classify.
- Returns:
- Band designation (e.g., “20m”, “40m”, “80m”) or “Unknown”
if frequency doesn’t match any known FT8 band.
- Return type:
str
Example
>>> parser = WsjtxParser(14.074) >>> band = parser.determine_band(14.076) >>> print(band) # "20m"
- frequency_handle(fq_offset: float)[source]¶
Convert WSJT-X frequency offset to absolute frequency.
WSJT-X sends frequency offsets in Hz relative to the dial frequency. This method converts the offset to MHz and adds it to the dial frequency to get the absolute transmission frequency.
- Parameters:
fq_offset (float) – Frequency offset in Hz from WSJT-X packet data. Typically ranges from 0 to 3000 Hz for FT8.
- Returns:
- Absolute frequency in MHz. Returns dial_frequency if offset
is invalid.
- Return type:
float
Example
>>> parser = WsjtxParser(14.074) >>> freq = parser.frequency_handle(1500.0) # 1500 Hz offset >>> print(freq) # 14.0755 MHz
- listen(host, port, processor: MessageProcessor)[source]¶
Main UDP listening loop.
Creates a UDP socket, binds to the specified host/port, and continuously listens for WSJT-X packets. Packets are parsed and valid ones are added to the processing queue. Also starts a background thread to move packets from the queue to the processor.
- Parameters:
host (str) – IP address to bind the UDP socket to.
port (int) – UDP port number to bind to.
processor (MessageProcessor) – Processor to handle parsed packets.
Note
This method runs in an infinite loop until a network error occurs. Uses a 1-second timeout on socket operations to prevent blocking.
- parse_packets(data)[source]¶
Parse binary WSJT-X packet data into structured Packet objects.
Decodes the binary UDP packet format used by WSJT-X to extract message information including SNR, frequency offset, timestamp delta, and the decoded message text. Currently handles message packets (type 2) and ignores status packets (type 1).
- Parameters:
data (bytes) – Raw UDP packet data from WSJT-X, minimum 12 bytes.
- The WSJT-X packet format includes:
Header: Magic number, schema version, packet type
Message data: SNR, time delta, frequency offset, message text
- Example packet structure for type 2 (message):
[0:4] Magic number [4:8] Schema version [8:12] Message type (2 for decoded messages) [27:31] SNR in dB [31:39] Time delta in seconds [39:43] Frequency offset in Hz [52:-2] UTF-8 encoded message text
- start_grabbing(processor: MessageProcessor)[source]¶
Background thread to transfer packets from queue to processor.
Continuously monitors the packet queue and transfers parsed packets to the MessageProcessor’s data store. Runs in an infinite loop with a 1-second timeout to prevent blocking.
- Parameters:
processor (MessageProcessor) – Processor instance to receive packets.
Note
This method runs in a separate thread and handles queue.Empty exceptions gracefully to avoid blocking when no packets are available.
- start_listening(host, port, processor: MessageProcessor)[source]¶
Start the UDP listening process with user confirmation.
Prompts the user to confirm before starting packet capture, then launches the UDP listener in a separate thread. This is the main entry point for beginning FT8 packet capture.
- Parameters:
host (str) – IP address to bind to, typically ‘127.0.0.1’ for localhost.
port (int) – UDP port number, typically 2237 for WSJT-X.
processor (MessageProcessor) – Processor instance to handle parsed packets.
Example
>>> parser = WsjtxParser(14.074) >>> processor = MessageProcessor() >>> parser.start_listening('127.0.0.1', 2237, processor) Ready to listen on 127.0.0.1:2237... Begin packet parsing? (Y/n)
Processor Module¶
- class ft8decoder.processor.MessageProcessor(log_level=20)[source]¶
Bases:
object
Processes and categorizes FT8 messages into QSOs, CQs, and miscellaneous communications.
This class takes parsed FT8 packets and intelligently categorizes them based on message content and structure. It tracks complete QSO (contact) sequences, identifies CQ calls, handles grid square exchanges, and provides data export and mapping functionality.
The processor understands FT8 protocol semantics including: - CQ calls (general and targeted) - Two-way QSO establishment and completion - Signal reports and grid square exchanges - Various acknowledgment and sign-off messages
- logger¶
Logger for this class
- Type:
logging.Logger
- cqs¶
List of unmatched CQ calls
- Type:
list
- qso_coords¶
Coordinates for completed QSOs with grid squares
- Type:
list
- cq_coords¶
Coordinates for CQ calls with grid squares
- Type:
list
- grid_square_cache¶
Cache mapping callsigns to their grid squares
- Type:
dict
- data_motherload¶
Raw packet buffer from parser
- Type:
list
- misc_comms¶
Miscellaneous communications that don’t fit QSO pattern
- Type:
dict
- qso_dict¶
Complete QSO conversations indexed by sorted callsign pairs
- Type:
dict
- translation_templates¶
Templates for translating special CQ types
- Type:
dict
- master_data¶
Combined view of all processed data
- Type:
list
Example
>>> processor = MessageProcessor() >>> processor.start(seconds=5) # Process packets every 5 seconds >>> # After some time... >>> processor.to_json("ft8_data") # Export all data >>> processor.to_map("ft8_map") # Create world map
- add_cq(callsigns: list)[source]¶
Link CQ calls to newly started QSOs.
When a new QSO begins, this method searches for any matching CQ call from one of the participants and incorporates it as the first turn of the conversation. This provides complete context for how the contact was initiated.
- Parameters:
callsigns (list) – Sorted pair of callsigns starting a new QSO.
- Process:
Search through unmatched CQ calls
Find CQ from either callsign in the new QSO
Convert CQ to MessageTurn and insert as turn 1
Remove CQ from unmatched list
Example
>>> # Previous CQ: "CQ W1ABC FN42" >>> # New QSO starts: "W1ABC K2DEF" >>> add_cq(["K2DEF", "W1ABC"]) >>> # CQ becomes turn 1 of the W1ABC/K2DEF conversation
- comms_to_json(filename: str)[source]¶
Export QSO conversation data to JSON file.
Serializes all completed and in-progress QSO conversations to a JSON file for analysis, archival, or import into other applications. Each QSO is indexed by the sorted callsign pair and contains all message turns with metadata.
- Parameters:
filename (str) – Output filename, .json extension added if missing.
- Raises:
IOError – If file cannot be written due to permissions or disk space.
OSError – If filename/path is invalid.
- JSON Structure:
- {
- “COMMS”: [{
- “(‘CALL1’, ‘CALL2’)”: [
{“completed”: false}, {MessageTurn data…}, {MessageTurn data…}
]
}]
}
Example
>>> processor.comms_to_json("my_qsos") >>> # Creates my_qsos.json with all QSO data
- cqs_to_json(filename: str)[source]¶
Export unanswered CQ calls to JSON file.
Saves all CQ calls that have not yet been matched to QSO conversations. Useful for analyzing calling patterns, popular frequencies, and propagation conditions.
- Parameters:
filename (str) – Output filename, .json extension added if missing.
- Raises:
IOError – If file cannot be written.
OSError – If filename/path is invalid.
- JSON Structure:
- {
- “CQS”: [
{CQ object data…}, {CQ object data…}
]
}
Example
>>> processor.cqs_to_json("unanswered_cqs") >>> # Creates unanswered_cqs.json with CQ data
- gather_coords()[source]¶
Collect and resolve geographic coordinates for QSOs and CQ calls.
Processes the grid square cache to convert Maidenhead locators into latitude/longitude coordinates for mapping purposes. Creates coordinate tuples for both QSOs (with connection lines, as long as both participants have sent their grid squares) and CQ calls (as individual points).
- Coordinate Resolution Process:
Check QSO participants for cached grid squares
Resolve grid squares to lat/lon coordinates
Create QSO coordinate tuples with both endpoints
Process CQ calls similarly for standalone points
- Populates:
self.qso_coords: List of QSO coordinate tuples self.cq_coords: List of CQ coordinate tuples
- QSO Coordinate Format:
((callsign1, lat1, lon1), (callsign2, lat2, lon2), (timestamp,))
- CQ Coordinate Format:
(message, timestamp, latitude, longitude)
Example
>>> processor.gather_coords() >>> print(f"Found {len(processor.qso_coords)} QSOs with coordinates") >>> print(f"Found {len(processor.cq_coords)} CQs with coordinates")
- handle_ack_reply(callsigns: list, packet: Packet, message: list)[source]¶
Process acknowledgment and sign-off messages in QSOs.
Handles the final stages of FT8 QSOs where stations confirm receipt of information and formally conclude the contact. Different acknowledgment types have specific meanings and some mark the QSO as completed.
- Parameters:
callsigns (list) – Sorted pair of callsigns involved in the QSO.
packet (Packet) – The packet containing the acknowledgment.
message (list) – Message words, with acknowledgment code as last element.
- Acknowledgment Processing:
“RRR”: Simple confirmation, QSO implied complete
“RR73”: Confirmation + goodbye, marks QSO as completed
“73”: Goodbye message, marks QSO as completed
Example
>>> # Message: ["W1ABC", "K2DEF", "RR73"] >>> handle_ack_reply(["K2DEF", "W1ABC"], packet, message) >>> # Marks QSO as completed and adds final turn
- handle_cq(packet: Packet)[source]¶
Process CQ (calling any station) messages.
CQ calls are the foundation of amateur radio contacts, indicating that a station is available for communication. This method handles various CQ formats from simple general calls to complex targeted calls with event indicators.
- Parameters:
packet (Packet) – The packet containing the CQ message.
- CQ Message Formats:
2 words: “CQ CALLSIGN” (general call)
3 words: “CQ CALLSIGN GRID” (call with location)
4 words: “CQ EVENT CALLSIGN GRID” (targeted/special event call)
Example
>>> handle_cq(packet) # packet.message = "CQ W1ABC FN42" >>> # Creates: "Station W1ABC is calling for any response from grid FN42."
- handle_grid_square(callsigns: list, packet: Packet, message: list)[source]¶
Process grid square location exchanges in QSOs.
Grid square exchanges are a standard part of FT8 QSOs, allowing operators to share their geographic locations. The grid square is cached for later use in mapping and coordinate resolution.
- Parameters:
callsigns (list) – Sorted pair of callsigns involved in the QSO.
packet (Packet) – The packet containing the grid square.
message (list) – Message words, with grid square as the last element.
Example
>>> # Message: ["W1ABC", "K2DEF", "FN42"] >>> handle_grid_square(["K2DEF", "W1ABC"], packet, message) >>> # Creates: "K2DEF sends a grid square location of FN42 to W1ABC."
- handle_longer_msg(packet: Packet, message: list)[source]¶
Process messages with more than three words.
Handles specialized CQ calls that include specific targets or event indicators. These four-word messages typically follow the format: “CQ EVENT CALLSIGN GRID” where EVENT specifies the type of activity or geographic target.
- Parameters:
packet (Packet) – The packet containing the multi-word message.
message (list) – List of words from the message (4+ words expected).
- Expected Format:
message[0]: “CQ” (already verified by caller) message[1]: Event/target code (e.g., “DX”, “POTA”, “TEST”, “NA”) message[2]: Calling station’s callsign message[3]: Calling station’s grid square
Example
>>> handle_longer_msg(packet, ["CQ", "POTA", "W1ABC", "FN42"]) >>> # Creates: "Parks on the Air participant W1ABC is calling from grid FN42."
- handle_short_msg(packet: Packet, message: list)[source]¶
Process two-word FT8 messages.
Handles various two-word message types including grid square announcements, sign-offs, acknowledgments, and QRP (low power) indicators. These messages are typically not part of structured QSOs but provide important information or conclude conversations.
- Parameters:
packet (Packet) – The packet containing the two-word message.
message (list) – List of two words from the message.
- Message Types:
Grid announcements: “CALLSIGN GRID” (e.g., “W1ABC FN42”)
Sign-offs: “CALLSIGN 73” (goodbye message)
Roger + sign-off: “CALLSIGN RR73” (acknowledgment + goodbye)
QRP indicators: “CALLSIGN/QRP CALLSIGN” (low power operations)
Simple pings: “CALLSIGN1 CALLSIGN2” (basic contact attempt)
Example
>>> handle_short_msg(packet, ["W1ABC", "FN42"]) # Grid announcement >>> handle_short_msg(packet, ["W1ABC", "73"]) # Sign-off >>> handle_short_msg(packet, ["W1ABC/QRP", "K2DEF"]) # QRP ping
- handle_signal_report(callsigns: list, packet: Packet, message: list)[source]¶
Process FT8 signal report exchanges.
Signal reports are a critical part of FT8 QSOs, indicating how well each station is receiving the other. This method creates a MessageTurn object with appropriate human-readable translation and adds it to the ongoing QSO conversation.
- Parameters:
callsigns (list) – Sorted pair of callsigns involved in the QSO.
packet (Packet) – The packet containing the signal report.
message (list) – Message words, with signal report as the last element.
- Signal Report Translation:
Reports with ‘R’ prefix indicate acknowledgment of previous report
Numeric value represents signal-to-noise ratio in dB
Positive values indicate strong signals, negative indicate weak
Example
>>> # Message: ["W1ABC", "K2DEF", "R-08"] >>> handle_signal_report(["K2DEF", "W1ABC"], packet, message) >>> # Creates: "K2DEF says Roger and reports a signal report of -08 to W1ABC."
- is_ack_reply(message)[source]¶
Determine if a message is an acknowledgment or sign-off.
FT8 conversations typically end with acknowledgment codes that confirm receipt of information and/or indicate the QSO is complete.
- Parameters:
message (list) – List of words from the FT8 message.
- Returns:
True if the message ends with a recognized acknowledgment code.
- Return type:
bool
- Acknowledgment Types:
“RRR”: Roger Roger Roger (confirmation received)
“RR73”: Roger Roger + 73 (confirmation + goodbye)
“73”: Best wishes/goodbye (QSO completion)
Example
>>> is_ack_reply(["W1ABC", "K2DEF", "RRR"]) # True >>> is_ack_reply(["W1ABC", "K2DEF", "RR73"]) # True >>> is_ack_reply(["W1ABC", "K2DEF", "FN42"]) # False
- is_grid_square(message)[source]¶
Determine if a message contains a Maidenhead grid square locator.
Maidenhead grid squares are a coordinate system used by amateur radio operators to specify geographic location. They follow the format of two uppercase letters followed by two digits (e.g., FN42, IO91).
- Parameters:
message (list) – List of words from the FT8 message.
- Returns:
True if the last word is a valid 4-character grid square.
- Return type:
bool
- Grid Square Format:
Character 1: Uppercase letter (A-R, longitude field)
Character 2: Uppercase letter (A-R, latitude field)
Character 3: Digit (0-9, longitude square)
Character 4: Digit (0-9, latitude square)
Example
>>> is_grid_square(["W1ABC", "K2DEF", "FN42"]) # True (valid grid) >>> is_grid_square(["W1ABC", "K2DEF", "fn42"]) # False (lowercase) >>> is_grid_square(["W1ABC", "K2DEF", "FN4"]) # False (too short)
- is_signal_report(message: list)[source]¶
Determine if a message contains an FT8 signal report.
FT8 signal reports are numeric values (typically -24 to +50 dB) that indicate signal strength and decoding quality. They may be prefixed with ‘R’ (received/roger) or ‘RR’ (roger roger) to indicate acknowledgment.
- Parameters:
message (list) – List of words from the FT8 message.
- Returns:
True if the last word appears to be a signal report.
- Return type:
bool
- Signal Report Formats:
Simple: “+05”, “-15”, “00” (raw SNR values)
Roger: “R+05”, “R-15” (acknowledging receipt)
Roger Roger: “RR+05”, “RR-15” (confirming exchange)
Example
>>> is_signal_report(["W1ABC", "K2DEF", "-15"]) # True >>> is_signal_report(["W1ABC", "K2DEF", "R+05"]) # True >>> is_signal_report(["W1ABC", "K2DEF", "73"]) # False
- misc_to_json(filename: str)[source]¶
Export miscellaneous communications to JSON file.
Saves communications that don’t fit the standard QSO pattern, including grid announcements, standalone sign-offs, and unrecognized message formats. Useful for debugging message parsing and analyzing non-standard activity.
- Parameters:
filename (str) – Output filename, .json extension added if missing.
- Raises:
IOError – If file cannot be written.
OSError – If filename/path is invalid.
Example
>>> processor.misc_to_json("misc_messages") >>> # Creates misc_messages.json
- organize_messages(seconds: int)[source]¶
Main message processing loop that categorizes FT8 messages.
This method runs continuously in a background thread, processing accumulated packets at regular intervals. It handles the complete FT8 message classification workflow:
Copies and clears the packet buffer
Parses each message to identify type (CQ, QSO, misc)
Routes messages to appropriate handlers
Tracks QSO progression and completion
- Parameters:
seconds (int) – Sleep interval between processing cycles.
- Message Classification Logic:
CQ messages: Start with “CQ” keyword
Two-word messages: Grid squares, sign-offs, acknowledgments
Three-word messages: Standard QSO exchanges (callsign pairs + data)
Four+ word messages: Special CQs with targets/events
- Example message flows:
>>> # CQ sequence >>> "CQ W1ABC FN42" -> handle_cq() >>> "W1ABC K2DEF" -> new QSO started >>> "K2DEF W1ABC -15" -> signal report >>> "W1ABC K2DEF FN42" -> grid square >>> "K2DEF W1ABC RRR" -> acknowledgment >>> "W1ABC K2DEF 73" -> QSO completed
- resolve_grid_square(grid_square)[source]¶
Convert Maidenhead grid square to latitude/longitude coordinates.
Uses the maidenhead library to convert 4-character grid squares into decimal degree coordinates for mapping and distance calculations. Returns a dictionary with coordinate information and a Google Maps link.
- Parameters:
grid_square (str) – 4-character Maidenhead grid square (e.g., “FN42”).
- Returns:
- Dictionary containing grid square, coordinates, and map URL.
Returns None if conversion fails.
- Return type:
dict or None
- Return Format:
- {
“Grid Square”: “FN42”, “Latitude”: “42.5”, “Longitude”: “-71.5”, “Map URL”: “https://www.google.com/maps?q=42.5,-71.5”
}
Example
>>> coords = resolve_grid_square("FN42") >>> print(f"Location: {coords['Latitude']}, {coords['Longitude']}") >>> # Location: 42.5, -71.5
- sort_message(packet: Packet, callsigns: list, new_convo: bool)[source]¶
Route QSO messages to appropriate handlers based on content.
This method analyzes three-word FT8 messages (typically callsign pairs plus additional data) and routes them to specialized handlers based on the message type. For new conversations, it also searches for and incorporates any matching CQ call.
- Parameters:
packet (Packet) – The packet containing the message to process.
callsigns (list) – Sorted list of two callsigns from the message.
new_convo (bool) – True if this is the first message in a QSO.
- Message Types Handled:
Acknowledgments: RRR, RR73, 73 (conversation enders)
Grid squares: 4-character locator codes (e.g., FN42, IO91)
Signal reports: Numeric SNR values with optional R/RR prefix
Unknown: Added to misc_comms for manual review
Example
>>> # New QSO starting >>> sort_message(packet, ['K2DEF', 'W1ABC'], new_convo=True) >>> # Continues existing QSO >>> sort_message(packet, ['K2DEF', 'W1ABC'], new_convo=False)
- start(seconds=5)[source]¶
Start the message processing thread.
Launches a background thread that periodically processes accumulated packets from the data buffer. The thread runs continuously, processing packets at the specified interval.
- Parameters:
seconds (int, optional) – Interval between processing cycles in seconds. Defaults to 5. Shorter intervals provide more real-time processing but use more CPU.
Example
>>> processor = MessageProcessor() >>> processor.start(seconds=3) # Process every 3 seconds
- to_json(filename: str)[source]¶
Export all captured FT8 data to a comprehensive JSON file.
Creates a complete export containing QSO conversations, unanswered CQ calls, and miscellaneous communications in a single file. This is the most comprehensive export option for complete session analysis.
- Parameters:
filename (str) – Output filename, .json extension added if missing.
- Raises:
IOError – If file cannot be written due to permissions or disk space.
OSError – If filename/path is invalid.
- JSON Structure:
- {
“COMMS”: [{QSO conversations…}], “CQS”: [{CQ calls…}], “MISC. COMMS”: [{miscellaneous messages…}]
}
Example
>>> processor.to_json("complete_session") >>> # Creates complete_session.json with all data types
- to_map(filename: str, all_cqs: bool = True)[source]¶
Generate an interactive world map of FT8 activity.
Creates a Folium-based HTML map showing QSO connections as lines between stations and CQ calls as individual markers. The map is automatically centered based on QSO activity and includes interactive layers for different data types.
- Parameters:
filename (str) – Output filename for the HTML map (without .html extension).
all_cqs (bool, optional) – If True, show all CQ calls. If False, only show CQs from stations that have not participated in a QSO. Defaults to True.
- Raises:
Exception – If map generation fails due to coordinate resolution errors or file writing issues.
- Map Features:
QSO participants: Green radio icons with callsign popups
QSO connections: Blue lines connecting stations with QSO details
CQ calls: Red radio icons for unanswered calls
Layer control: Toggle between QSOs and CQs
Auto-centering: Map centers on mean QSO coordinates
- Map Centering Logic:
If 3+ QSOs with coordinates: Centers on mean lat/lon of all participants
If <3 QSOs: Uses default world view (0,0) coordinates
Example
>>> processor.to_map("activity_map") >>> # Creates activity_map.html with all QSOs and CQs >>> processor.to_map("qso_only", all_cqs=False) >>> # Creates qso_only.html showing only successful contacts
CLI Module¶
- ft8decoder.cli.main()[source]¶
Main entry point for the FT8 Decoder command-line interface.
Provides a comprehensive CLI for capturing, processing, and exporting FT8 messages from WSJT-X. Supports real-time packet capture with configurable processing intervals and multiple export formats including JSON data files and interactive world maps.
- Command Structure:
ft8decoder listen [options]
- Key Features:
Real-time FT8 packet capture from WSJT-X UDP stream
Intelligent message classification (QSOs, CQs, misc communications)
Multiple export formats (JSON, interactive maps)
Configurable processing intervals and capture duration
Automatic band detection and frequency calculation
- Example Usage:
$ python main.py listen –dial 14.074 –duration 300 –export-all session1 $ python main.py listen –port 2237 –interval 10 –to-map activity_map $ python main.py listen –host 192.168.1.100 –export-comms qsos_only