From 6becf68ebfaa6625d3ae2e6ab33bde418dc2b699 Mon Sep 17 00:00:00 2001 From: Mark Jessop Date: Sat, 4 Sep 2021 19:17:45 +0930 Subject: [PATCH] Updates to support v2 telemetry --- README.md | 5 ++--- horusgui/__init__.py | 2 +- horusgui/config.py | 28 +++++++++++++++++++--------- horusgui/gui.py | 24 ++++++++++++++++++++---- pyproject.toml | 4 ++-- requirements.txt | 2 +- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3aedbb9..e962fda 100755 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ Telemetry demodulator for the following modems in use by Project Horus * Horus Binary Modes (4FSK) * v1 - Legacy 22 byte mode, Golay(23,12) FEC - * v2 - 16/32-byte modes, LDPC FEC (Under development) + * v2 - 32-byte mode, Golay(23,12) FEC * RTTY (7N1, 7N2 and 8N2, standard [UKHAS sentences](https://ukhas.org.uk/communication:protocol) with CRC16 only) -This project serves as a graphical front-end to [horusdemodlib](https://github.com/projecthorus/horusdemodlib) a Python/C library of telemetry demodulators based off the [codec2](https://github.com/drowe67/codec2) FSK modem. The core modem used in this library is very well tested, and performs in line with incoherent FSK demodulator theory. The RTTY decoder is approximately [2dB better](http://www.rowetel.com/?p=5906) than dl-fldigi, and the Horus Binary v1 modem approximately 7 dB better again. Once finished, the Horus Binary v2 modes should provide more flexibility over the v1 mode, and provide further performance improvements. +This project serves as a graphical front-end to [horusdemodlib](https://github.com/projecthorus/horusdemodlib) a Python/C library of telemetry demodulators based off the [codec2](https://github.com/drowe67/codec2) FSK modem. The core modem used in this library is very well tested, and performs in line with incoherent FSK demodulator theory. The RTTY decoder is approximately [2dB better](http://www.rowetel.com/?p=5906) than dl-fldigi, and the Horus Binary modem approximately 7 dB better again. The Horus Binary v2 mode provides some additional flexibility over the v1 mode, allowing the addition of custom telemetry fields. ### Important Performance Notes The FSK demodulator at the core of this application expects the transmitter to behave like a modem. That is, it should: @@ -25,7 +25,6 @@ Written by: * Python Library - Mark Jessop * FSK Modem - [David Rowe](http://rowetel.com) * FSK Modem Python Wrapper - [XSSFox](https://twitter.com/xssfox) -* LDPC Codes - [Bill Cowley](http://lowsnr.org/) ![Screenshot](doc/horusgui_screenshot.png) diff --git a/horusgui/__init__.py b/horusgui/__init__.py index 86205cb..3ced358 100755 --- a/horusgui/__init__.py +++ b/horusgui/__init__.py @@ -1 +1 @@ -__version__ = "0.1.17" +__version__ = "0.2.1" diff --git a/horusgui/config.py b/horusgui/config.py index a87fa19..d64c6ef 100644 --- a/horusgui/config.py +++ b/horusgui/config.py @@ -12,7 +12,7 @@ from ruamel.yaml import YAML from . import __version__ from .modem import populate_modem_settings from .audio import populate_sample_rates -from horusdemodlib.payloads import download_latest_payload_id_list, download_latest_custom_field_list +from horusdemodlib.payloads import download_latest_payload_id_list, download_latest_custom_field_list, read_payload_list, read_custom_field_list import horusdemodlib.payloads default_config = { @@ -69,7 +69,7 @@ def read_config(widgets): """ Read in configuration settings from Qt """ global qt_settings, default_config - OK_VERSIONS = [__version__, "0.1.15", "0.1.14"] + OK_VERSIONS = [__version__] # Try and read in the version parameter from QSettings if qt_settings.value("version") not in OK_VERSIONS: @@ -153,19 +153,24 @@ def save_config(widgets): write_config() -def init_payloads(): +def init_payloads(payload_id_list=None, custom_field_list=None): """ Attempt to download the latest payload / config data, and update local configs """ global default_config # Attempt to grab the payload list. - _payload_list = download_latest_payload_id_list(timeout=3) + if payload_id_list is None: + _payload_list = download_latest_payload_id_list(timeout=3) + else: + logging.info(f"Using supplied Payload ID list file: {payload_id_list}") + _payload_list = read_payload_list(payload_id_list) + if _payload_list: # Sanity check the result if 0 in _payload_list: horusdemodlib.payloads.HORUS_PAYLOAD_LIST = _payload_list logging.info(f"Updated Payload List Successfuly!") else: - logging.critical("Could not read downloaded payload list!") + logging.critical("Could not read payload list!") else: if 'payload_list' in default_config: # Maybe we have a stored config we can use. @@ -183,20 +188,25 @@ def init_payloads(): logging.info(f"Payload List contains {len(list(horusdemodlib.payloads.HORUS_PAYLOAD_LIST.keys()))} entries.") - _custom_fields = download_latest_custom_field_list(timeout=3) + if custom_field_list is None: + _custom_fields = download_latest_custom_field_list(timeout=3) + else: + logging.info(f"Using supplied Custom Field List file: {custom_field_list}") + _custom_fields = read_custom_field_list(custom_field_list) + if _custom_fields: # Sanity Check - if 'HORUSTEST' in _custom_fields: + if '4FSKTEST-V2' in _custom_fields: horusdemodlib.payloads.HORUS_CUSTOM_FIELDS = _custom_fields logging.info(f"Updated Custom Field List Successfuly!") else: - logging.critical("Could not read downloaded custom field list!") + logging.critical("Could not read custom field list!") else: if 'custom_field_list' in default_config: # Maybe we have a stored config we can use. try: _custom_fields = json.loads(default_config['custom_field_list']) - if 'HORUSTEST' in _custom_fields: + if '4FSKTEST-V2' in _custom_fields: horusdemodlib.payloads.HORUS_CUSTOM_FIELDS = _custom_fields logging.warning("Loaded Custom Fields List from local cache, may be out of date!") else: diff --git a/horusgui/gui.py b/horusgui/gui.py index dbfe92f..a0314d1 100644 --- a/horusgui/gui.py +++ b/horusgui/gui.py @@ -13,6 +13,7 @@ if sys.version_info < (3, 0): print("This script requires Python 3!") sys.exit(1) +import argparse import datetime import glob import logging @@ -39,8 +40,6 @@ from horusdemodlib.payloads import * from horusdemodlib.horusudp import send_payload_summary, send_ozimux_message from . import __version__ -# Setup Logging -logging.basicConfig(format="%(asctime)s %(levelname)s: %(message)s", level=logging.INFO) # A few hardcoded defaults DEFAULT_ESTIMATOR_MIN = 100 @@ -69,6 +68,23 @@ decoder_init = False # Global running indicator running = False +# Read command-line arguments +parser = argparse.ArgumentParser(description="Project Horus GUI", formatter_class=argparse.ArgumentDefaultsHelpFormatter) +parser.add_argument("--payload-id-list", type=str, default=None, help="Use supplied Payload ID List instead of downloading a new one.") +parser.add_argument("--custom-field-list", type=str, default=None, help="Use supplied Custom Field List instead of downloading a new one.") +parser.add_argument("-v", "--verbose", action="store_true", default=False, help="Verbose output (set logging level to DEBUG)") +args = parser.parse_args() + +if args.verbose: + _log_level = logging.DEBUG +else: + _log_level = logging.INFO + +# Setup Logging +logging.basicConfig( + format="%(asctime)s %(levelname)s: %(message)s", level=_log_level +) + # # GUI Creation - The Bad way. # @@ -914,7 +930,7 @@ def handle_log_update(log_update): # GUI Update Loop def processQueues(): """ Read in data from the queues, this decouples the GUI and async inputs somewhat. """ - global fft_update_queue, status_update_queue, decoder_init, widgets + global fft_update_queue, status_update_queue, decoder_init, widgets, args while fft_update_queue.qsize() > 0: _data = fft_update_queue.get() @@ -936,7 +952,7 @@ def processQueues(): if not decoder_init: # Initialise decoders, and other libraries here. - init_payloads() + init_payloads(payload_id_list = args.payload_id_list, custom_field_list = args.custom_field_list) decoder_init = True # Once initialised, enable the start button widgets["startDecodeButton"].setEnabled(True) diff --git a/pyproject.toml b/pyproject.toml index 93f077e..98beff0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "horusgui" -version = "0.1.17" +version = "0.2.1" description = "" authors = ["Mark Jessop "] @@ -12,7 +12,7 @@ PyQt5 = "^5.13.0" pyqtgraph = "^0.11.0" pyaudio = "^0.2.11" "ruamel.yaml" = "^0.16.10" -horusdemodlib = "^0.1.21" +horusdemodlib = "^0.2.2" [tool.poetry.dev-dependencies] diff --git a/requirements.txt b/requirements.txt index 6623feb..ee85993 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ PyQt5 pyqtgraph ruamel.yaml requests -horusdemodlib>=0.1.21 \ No newline at end of file +horusdemodlib>=0.2.2 \ No newline at end of file