PyFT8 2.11.0__tar.gz → 2.12.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {pyft8-2.11.0 → pyft8-2.12.1}/PKG-INFO +10 -10
  2. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/pskreporter.py +1 -1
  3. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/pyft8.py +39 -34
  4. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8.egg-info/PKG-INFO +10 -10
  5. {pyft8-2.11.0 → pyft8-2.12.1}/README.md +9 -9
  6. {pyft8-2.11.0 → pyft8-2.12.1}/pyproject.toml +1 -1
  7. {pyft8-2.11.0 → pyft8-2.12.1}/LICENSE +0 -0
  8. {pyft8-2.11.0 → pyft8-2.12.1}/MANIFEST.in +0 -0
  9. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/__init__.py +0 -0
  10. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/databases.py +0 -0
  11. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/gui.py +0 -0
  12. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/receiver.py +0 -0
  13. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/rigctrl.py +0 -0
  14. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/time_utils.py +0 -0
  15. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8/transmitter.py +0 -0
  16. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8.egg-info/SOURCES.txt +0 -0
  17. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8.egg-info/dependency_links.txt +0 -0
  18. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8.egg-info/entry_points.txt +0 -0
  19. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8.egg-info/requires.txt +0 -0
  20. {pyft8-2.11.0 → pyft8-2.12.1}/PyFT8.egg-info/top_level.txt +0 -0
  21. {pyft8-2.11.0 → pyft8-2.12.1}/setup.cfg +0 -0
  22. {pyft8-2.11.0 → pyft8-2.12.1}/tests/dev/CQ AAAA.py +0 -0
  23. {pyft8-2.11.0 → pyft8-2.12.1}/tests/dev/osd.py +0 -0
  24. {pyft8-2.11.0 → pyft8-2.12.1}/tests/dev/test_generate_wav.py +0 -0
  25. {pyft8-2.11.0 → pyft8-2.12.1}/tests/dev/test_loopback_performance.py +0 -0
  26. {pyft8-2.11.0 → pyft8-2.12.1}/tests/dev/view_worked_before.py +0 -0
  27. {pyft8-2.11.0 → pyft8-2.12.1}/tests/plot_baseline.py +0 -0
  28. {pyft8-2.11.0 → pyft8-2.12.1}/tests/spare.py +0 -0
  29. {pyft8-2.11.0 → pyft8-2.12.1}/tests/test_batch_and_live.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyFT8
3
- Version: 2.11.0
3
+ Version: 2.12.1
4
4
  Summary: FT8 Decoding and Encoding in Python with test/loopback code
5
5
  Author-email: G1OJS <g1ojs@yahoo.com>
6
6
  License-Expression: GPL-3.0-or-later
@@ -17,11 +17,9 @@ Requires-Dist: matplotlib
17
17
  Requires-Dist: pyaudio
18
18
  Dynamic: license-file
19
19
 
20
- # PyFT8 [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/pyft8) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=weekly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads/wk)](https://pepy.tech/projects/pyft8)
20
+ # PyFT8 [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/pyft8) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=weekly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads/wk)](https://pepy.tech/projects/pyft8) [PyPI link](https://pypi.org/project/PyFT8/)
21
21
  # All-Python FT8 Transceiver GUI / Command Line Modem
22
22
 
23
- **Note - my recent additions to the GUI have caused issues with the non-GUI based command line processing. I'm working on fixing this.**
24
-
25
23
  This repository contains the source code for PyFT8, an all-Python open source FT8 transceiver that you can run as a basic GUI or from the command line to receive and transmit. Decoding performance (number of decodes) is about 70% of that achieved by WSJT-x in NORM mode, but (tbc) slightly above ft8_lib.
26
24
 
27
25
  PyFT8 is somewhat experimental, with a focus on demonstrating FT8 written in Python, but can be used as a standalone replacement for WSJT-x and other software.
@@ -72,14 +70,16 @@ pip install PyFT8
72
70
 
73
71
  Once installed, you can use the following commands to run it. Otherwise, please download or browse the code, or fork the repo and play with it! If you do fork it, please check back here as I'm constantly (as of Jan 2026) rewriting and improving.
74
72
 
73
+ The use cases below are the ones held in the test cases at the bottom of the main pyft8.py file. Where a config folder and .ini file is required, if you leave off the '-c {folder}' option, you'll be asked if you want to create a .ini file in the current directory.
74
+
75
75
  |Usage | Command example| Notes |
76
76
  |----------------------|----------------------|----------------------|
77
- |Basic Rx GUI | pyft8 -i "Keyword1, Keyword2" | Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
78
- |GUI with transmit | pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" | Keywords identify the input (-i) and output (-o) sound devices. The transmit parts are under development.|
79
- | Command line Rx without a GUI | pyft8 -i "Keyword1, Keyword2" -n| |
80
- | Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90"| Tx on next cycle. You supply the PTT control method.|
81
- | Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90"| -w "Mywav.wav" can be omitted |
82
- | Launch configured GUI|pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" -c {config folder}| Config folder stores PyFT8.ini (your callsign, grid, buttons) and PyFT8.adi log file. Run this once to create default PyFT8.ini file.|
77
+ |Full GUI without Tx | pyft8 -i "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
78
+ |Rx only without GUI | pyft8 -i "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
79
+ |Full GUI with Tx| pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input (-i) and output (-o) sound devices.|
80
+ |Parse an 'ALL.txt' file in the specified config folder, save as json files, and exit| pyft8 -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg -a||
81
+ | Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Tx on next cycle. Config file is required to specify the rig control method. |
82
+ | Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90"| No config folder / .ini file required |
83
83
 
84
84
  ### Rig control
85
85
  I've included the Python code that I use with my Icom IC-7100 in the file 'rigctrl.py', and believe I've moved sufficient 'specification' for the rig protocol into the .ini file so that you can paste in your own rig specification (see for e.g. the Omnirig .ini file for your rig) and get it working with PyFT8 controlling PTT and frequency. I designed this code to drop the serial connection when it's not required, so that the rig's serial port can be accessed by other software at the same time (assuming that the other software returns the favour and doesn't permanently hog the serial port).
@@ -51,7 +51,7 @@ class PSKR_upload:
51
51
  self.rx_block = self._block(b"\x99\x92", rx)
52
52
  self.console_print = console_print
53
53
  self.lock = threading.Lock()
54
- print(f"[PSKR_upload] Spots will upload to pskreporter")
54
+ print(f"[PSKR_upload] Spots will upload to pskreporter if Rx band is known")
55
55
  threading.Thread(target = self._check_for_send, daemon = True).start()
56
56
 
57
57
  def _enc_str(self, s):
@@ -12,12 +12,12 @@ from PyFT8.time_utils import global_time_utils
12
12
  from PyFT8.rigctrl import Rig_CAT, Rig_hamlib
13
13
  from PyFT8.databases import History, ADIF
14
14
 
15
- VER = '2.11.0'
15
+ VER = '2.12.1'
16
16
 
17
17
  MAX_TX_START_SECONDS = 2.5
18
18
  HEARING_PANEL_LIFE_MINS = 5
19
19
  PSKR_REFRESH_MINS = 20
20
- rig, gui, qso, adif_logging, history, pskr_upload = None, None, None, None, None, None
20
+ config_folder, rig, gui, qso, adif_logging, history, pskr_upload, output_device_idx = None, None, None, None, None, None, None, None
21
21
  busy_profile, hearing_me = None, None
22
22
 
23
23
  def get_config():
@@ -323,14 +323,22 @@ def cli():
323
323
  parser.add_argument('-o','--outputcard_keywords', help = 'Comma-separated keywords to identify the output sound device')
324
324
  parser.add_argument('-n','--no_gui', action='store_true', help = "Don't create a gui")
325
325
  parser.add_argument('-m','--transmit_message', nargs='?', help = 'Transmit a message')
326
- parser.add_argument('-w','--wave_output_file', nargs='?', help = 'Wave output file name', default = 'PyFT8.wav')
326
+ parser.add_argument('-w','--wave_output_file', nargs='?', help = 'Wave output file name')
327
327
  parser.add_argument('-a', '--parse_all_file', action='store_true', help = 'parse and save .../config_folder/ALL.txt to heard me / heard by me data')
328
328
  args = parser.parse_args()
329
+
329
330
  if len(sys.argv)==1:
330
331
  parser.print_help(sys.stderr)
331
332
  sys.exit(1)
333
+
334
+ if args.transmit_message or args.outputcard_keywords:
335
+ audio_out = AudioOut()
336
+ clearest_frequency = 760
337
+
338
+ if args.transmit_message and args.wave_output_file:
339
+ make_wav(args.transmit_message, f"{args.wave_output_file}")
340
+ sys.exit(1)
332
341
 
333
- output_device_idx = None
334
342
  config_folder = f"{args.config_folder}".strip()
335
343
  get_config()
336
344
  mc, mg = config['station']['call'], config['station']['grid']
@@ -347,44 +355,41 @@ def cli():
347
355
  console_print("Connecting to rig via CAT")
348
356
  rig = Rig_CAT(config)
349
357
 
350
- if args.transmit_message or args.outputcard_keywords:
351
- audio_out = AudioOut()
352
- clearest_frequency = 760
353
-
354
358
  if args.outputcard_keywords:
355
359
  outputcard_keywords = args.outputcard_keywords.replace(' ','').split(',')
356
360
  output_device_idx = audio_out.find_device(outputcard_keywords)
357
-
358
- if args.transmit_message:
359
- if args.outputcard_keywords:
361
+
362
+ if args.transmit_message and rig and args.outputcard_keywords:
360
363
  qso.set_tx_message(args.transmit_message)
361
- else:
362
- make_wav(args.transmit_message, f"{config_folder}/{args.wave_output_file}")
363
- else:
364
- if not args.inputcard_keywords:
365
- print("No input device specified")
366
364
  sys.exit(1)
365
+
366
+ if not args.inputcard_keywords:
367
+ print("No input device specified")
368
+ sys.exit(1)
369
+ else:
367
370
  audio_in = AudioIn(3100)
368
371
  input_device_idx = audio_in.find_device(args.inputcard_keywords.replace(' ','').split(','))
369
372
  if not input_device_idx:
370
373
  console_print("No input device")
371
- else:
372
- gui = None
373
- if not args.no_gui:
374
- gui = Gui(audio_in.dBgrid_main, 4, 2, config, on_gui_sidebars_refresh, on_gui_msg_click, on_gui_control_click)
375
- history = History(config_folder, mc, mg, PSKR_REFRESH_MINS, args.parse_all_file)
376
- adif_logging = ADIF(f"{config_folder}/PyFT8.adi")
377
- history.load_from_wb(adif_logging.cache)
378
- if mc is not None and 'pskreporter' in config.keys():
379
- if config['pskreporter']['upload'] == 'Y':
380
- pskr_upload = PSKR_upload(mc, mg, software = f"PyFT8 v{VER}", console_print = console_print) if not mc is None else None
381
- rx = Receiver(audio_in, [200, 3100], on_rx_decode, on_rx_busy_profile)
382
- audio_in.start_streamed_audio(input_device_idx)
383
- if gui is not None:
384
- gui.set_bandstats_title(f"Pskreporter Spots\nto/from {config['station']['grid'][:4]} <{PSKR_REFRESH_MINS:.0f} mins")
385
- gui.plt.show()
386
- else:
387
- wait_for_keyboard()
374
+ sys.exit(1)
375
+ rx = Receiver(audio_in, [200, 3100], on_rx_decode, on_rx_busy_profile)
376
+ audio_in.start_streamed_audio(input_device_idx)
377
+
378
+ if not args.no_gui:
379
+ gui = Gui(audio_in.dBgrid_main, 4, 2, config, on_gui_sidebars_refresh, on_gui_msg_click, on_gui_control_click)
380
+ history = History(config_folder, mc, mg, PSKR_REFRESH_MINS, args.parse_all_file)
381
+ adif_logging = ADIF(f"{config_folder}/PyFT8.adi")
382
+ history.load_from_wb(adif_logging.cache)
383
+
384
+ if mc is not None and 'pskreporter' in config.keys():
385
+ if config['pskreporter']['upload'] == 'Y':
386
+ pskr_upload = PSKR_upload(mc, mg, software = f"PyFT8 v{VER}", console_print = console_print) if not mc is None else None
387
+
388
+ if gui is None:
389
+ wait_for_keyboard()
390
+ else:
391
+ gui.set_bandstats_title(f"Pskreporter Spots\nto/from {config['station']['grid'][:4]} <{PSKR_REFRESH_MINS:.0f} mins")
392
+ gui.plt.show()
388
393
 
389
394
 
390
395
  #================== TEST CODE ============================================================
@@ -394,6 +399,6 @@ if __name__ == "__main__":
394
399
  #with mock.patch('sys.argv', ['pyft8', '-c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg', '-a']):
395
400
  #with mock.patch('sys.argv', ['pyft8', '-i Mic, CODEC', '-c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg']):
396
401
  #with mock.patch('sys.argv', ['pyft8', '-i Mic, CODEC', '-n', '-c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg']):
397
- #with mock.patch('sys.argv', ['pyft8', '-m', "CQ G1OJS IO90", '-c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg']):
402
+ #with mock.patch('sys.argv', ['pyft8', '-m', "CQ G1OJS IO90", "-w", "PyFT8.wav"]):
398
403
  #with mock.patch('sys.argv', ['pyft8', '-m', "CQ G1OJS IO90", '-o', "Speak, CODEC", '-c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg']):
399
404
  cli()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyFT8
3
- Version: 2.11.0
3
+ Version: 2.12.1
4
4
  Summary: FT8 Decoding and Encoding in Python with test/loopback code
5
5
  Author-email: G1OJS <g1ojs@yahoo.com>
6
6
  License-Expression: GPL-3.0-or-later
@@ -17,11 +17,9 @@ Requires-Dist: matplotlib
17
17
  Requires-Dist: pyaudio
18
18
  Dynamic: license-file
19
19
 
20
- # PyFT8 [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/pyft8) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=weekly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads/wk)](https://pepy.tech/projects/pyft8)
20
+ # PyFT8 [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/pyft8) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=weekly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads/wk)](https://pepy.tech/projects/pyft8) [PyPI link](https://pypi.org/project/PyFT8/)
21
21
  # All-Python FT8 Transceiver GUI / Command Line Modem
22
22
 
23
- **Note - my recent additions to the GUI have caused issues with the non-GUI based command line processing. I'm working on fixing this.**
24
-
25
23
  This repository contains the source code for PyFT8, an all-Python open source FT8 transceiver that you can run as a basic GUI or from the command line to receive and transmit. Decoding performance (number of decodes) is about 70% of that achieved by WSJT-x in NORM mode, but (tbc) slightly above ft8_lib.
26
24
 
27
25
  PyFT8 is somewhat experimental, with a focus on demonstrating FT8 written in Python, but can be used as a standalone replacement for WSJT-x and other software.
@@ -72,14 +70,16 @@ pip install PyFT8
72
70
 
73
71
  Once installed, you can use the following commands to run it. Otherwise, please download or browse the code, or fork the repo and play with it! If you do fork it, please check back here as I'm constantly (as of Jan 2026) rewriting and improving.
74
72
 
73
+ The use cases below are the ones held in the test cases at the bottom of the main pyft8.py file. Where a config folder and .ini file is required, if you leave off the '-c {folder}' option, you'll be asked if you want to create a .ini file in the current directory.
74
+
75
75
  |Usage | Command example| Notes |
76
76
  |----------------------|----------------------|----------------------|
77
- |Basic Rx GUI | pyft8 -i "Keyword1, Keyword2" | Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
78
- |GUI with transmit | pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" | Keywords identify the input (-i) and output (-o) sound devices. The transmit parts are under development.|
79
- | Command line Rx without a GUI | pyft8 -i "Keyword1, Keyword2" -n| |
80
- | Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90"| Tx on next cycle. You supply the PTT control method.|
81
- | Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90"| -w "Mywav.wav" can be omitted |
82
- | Launch configured GUI|pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" -c {config folder}| Config folder stores PyFT8.ini (your callsign, grid, buttons) and PyFT8.adi log file. Run this once to create default PyFT8.ini file.|
77
+ |Full GUI without Tx | pyft8 -i "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
78
+ |Rx only without GUI | pyft8 -i "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
79
+ |Full GUI with Tx| pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input (-i) and output (-o) sound devices.|
80
+ |Parse an 'ALL.txt' file in the specified config folder, save as json files, and exit| pyft8 -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg -a||
81
+ | Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Tx on next cycle. Config file is required to specify the rig control method. |
82
+ | Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90"| No config folder / .ini file required |
83
83
 
84
84
  ### Rig control
85
85
  I've included the Python code that I use with my Icom IC-7100 in the file 'rigctrl.py', and believe I've moved sufficient 'specification' for the rig protocol into the .ini file so that you can paste in your own rig specification (see for e.g. the Omnirig .ini file for your rig) and get it working with PyFT8 controlling PTT and frequency. I designed this code to drop the serial connection when it's not required, so that the rig's serial port can be accessed by other software at the same time (assuming that the other software returns the favour and doesn't permanently hog the serial port).
@@ -1,8 +1,6 @@
1
- # PyFT8 [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/pyft8) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=weekly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads/wk)](https://pepy.tech/projects/pyft8)
1
+ # PyFT8 [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/pyft8) [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyft8?period=weekly&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads/wk)](https://pepy.tech/projects/pyft8) [PyPI link](https://pypi.org/project/PyFT8/)
2
2
  # All-Python FT8 Transceiver GUI / Command Line Modem
3
3
 
4
- **Note - my recent additions to the GUI have caused issues with the non-GUI based command line processing. I'm working on fixing this.**
5
-
6
4
  This repository contains the source code for PyFT8, an all-Python open source FT8 transceiver that you can run as a basic GUI or from the command line to receive and transmit. Decoding performance (number of decodes) is about 70% of that achieved by WSJT-x in NORM mode, but (tbc) slightly above ft8_lib.
7
5
 
8
6
  PyFT8 is somewhat experimental, with a focus on demonstrating FT8 written in Python, but can be used as a standalone replacement for WSJT-x and other software.
@@ -53,14 +51,16 @@ pip install PyFT8
53
51
 
54
52
  Once installed, you can use the following commands to run it. Otherwise, please download or browse the code, or fork the repo and play with it! If you do fork it, please check back here as I'm constantly (as of Jan 2026) rewriting and improving.
55
53
 
54
+ The use cases below are the ones held in the test cases at the bottom of the main pyft8.py file. Where a config folder and .ini file is required, if you leave off the '-c {folder}' option, you'll be asked if you want to create a .ini file in the current directory.
55
+
56
56
  |Usage | Command example| Notes |
57
57
  |----------------------|----------------------|----------------------|
58
- |Basic Rx GUI | pyft8 -i "Keyword1, Keyword2" | Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
59
- |GUI with transmit | pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" | Keywords identify the input (-i) and output (-o) sound devices. The transmit parts are under development.|
60
- | Command line Rx without a GUI | pyft8 -i "Keyword1, Keyword2" -n| |
61
- | Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90"| Tx on next cycle. You supply the PTT control method.|
62
- | Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90"| -w "Mywav.wav" can be omitted |
63
- | Launch configured GUI|pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" -c {config folder}| Config folder stores PyFT8.ini (your callsign, grid, buttons) and PyFT8.adi log file. Run this once to create default PyFT8.ini file.|
58
+ |Full GUI without Tx | pyft8 -i "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
59
+ |Rx only without GUI | pyft8 -i "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input sound device - partial match is fine, e.g. "Mic, CODEC"|
60
+ |Full GUI with Tx| pyft8 -i "Keyword1, Keyword2" -o "Keyword1, Keyword2" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Keywords identify the input (-i) and output (-o) sound devices.|
61
+ |Parse an 'ALL.txt' file in the specified config folder, save as json files, and exit| pyft8 -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg -a||
62
+ | Command line transmit | pyft8 -o "Keyword1, Keyword2" -m "CQ G1OJS IO90" -c C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg| Tx on next cycle. Config file is required to specify the rig control method. |
63
+ | Command line create a wav file | pyft8 -w "Mywav.wav" -m "CQ G1OJS IO90"| No config folder / .ini file required |
64
64
 
65
65
  ### Rig control
66
66
  I've included the Python code that I use with my Icom IC-7100 in the file 'rigctrl.py', and believe I've moved sufficient 'specification' for the rig protocol into the .ini file so that you can paste in your own rig specification (see for e.g. the Omnirig .ini file for your rig) and get it working with PyFT8 controlling PTT and frequency. I designed this code to drop the serial connection when it's not required, so that the rig's serial port can be accessed by other software at the same time (assuming that the other software returns the favour and doesn't permanently hog the serial port).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "PyFT8"
3
- version = "2.11.0"
3
+ version = "2.12.1"
4
4
  license = "GPL-3.0-or-later"
5
5
 
6
6
  authors = [
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes