v0.1.20 Updates

pull/13/head
Mark Jessop 2020-10-05 17:54:15 +10:30
rodzic 1e0f5b1456
commit de1de7d52f
6 zmienionych plików z 100 dodań i 13 usunięć

Wyświetl plik

@ -1 +1 @@
__version__ = "0.1.12"
__version__ = "0.1.14"

Wyświetl plik

@ -29,6 +29,8 @@ default_config = {
"habitat_radio": "",
"horus_udp_enabled": True,
"horus_udp_port": 55672,
"ozimux_enabled": False,
"ozimux_udp_port": 55683,
"payload_list": json.dumps(horusdemodlib.payloads.HORUS_PAYLOAD_LIST),
"custom_field_list": json.dumps({})
}
@ -87,6 +89,8 @@ def read_config(widgets):
# Horus Settings
widgets["horusUploadSelector"].setChecked(ValueToBool(default_config["horus_udp_enabled"]))
widgets["horusUDPEntry"].setText(str(default_config["horus_udp_port"]))
widgets["ozimuxUploadSelector"].setChecked(ValueToBool(default_config["ozimux_enabled"]))
widgets["ozimuxUDPEntry"].setText(str(default_config["ozimux_udp_port"]))
# Try and set the audio device.
# If the audio device is not in the available list of devices, this will fail silently.
@ -133,6 +137,8 @@ def save_config(widgets):
default_config["habitat_radio"] = widgets["userRadioEntry"].text()
default_config["horus_udp_enabled"] = widgets["horusUploadSelector"].isChecked()
default_config["horus_udp_port"] = int(widgets["horusUDPEntry"].text())
default_config["ozimux_enabled"] = widgets["ozimuxUploadSelector"].isChecked()
default_config["ozimux_udp_port"] = int(widgets["ozimuxUDPEntry"].text())
default_config["audio_device"] = widgets["audioDeviceSelector"].currentText()
default_config["audio_sample_rate"] = widgets["audioSampleRateSelector"].currentText()
default_config["modem"] = widgets["horusModemSelector"].currentText()
@ -150,7 +156,7 @@ def init_payloads():
global default_config
# Attempt to grab the payload list.
_payload_list = download_latest_payload_id_list()
_payload_list = download_latest_payload_id_list(timeout=3)
if _payload_list:
# Sanity check the result
if 0 in _payload_list:
@ -175,7 +181,7 @@ 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()
_custom_fields = download_latest_custom_field_list(timeout=3)
if _custom_fields:
# Sanity Check
if 'HORUSTEST' in _custom_fields:

Wyświetl plik

@ -16,6 +16,7 @@ if sys.version_info < (3, 0):
import datetime
import glob
import logging
import platform
import pyqtgraph as pg
import numpy as np
from queue import Queue
@ -35,7 +36,7 @@ from .icon import getHorusIcon
from horusdemodlib.demod import HorusLib, Mode
from horusdemodlib.decoder import decode_packet, parse_ukhas_string
from horusdemodlib.payloads import *
from horusdemodlib.horusudp import send_payload_summary
from horusdemodlib.horusudp import send_payload_summary, send_ozimux_message
from . import __version__
# Setup Logging
@ -125,6 +126,7 @@ d0.addWidget(w1_audio)
w1_modem = pg.LayoutWidget()
# Modem Parameters
widgets["horusModemLabel"] = QtGui.QLabel("<b>Mode:</b>")
widgets["horusModemSelector"] = QtGui.QComboBox()
@ -134,11 +136,28 @@ widgets["horusModemRateSelector"] = QtGui.QComboBox()
widgets["horusMaskEstimatorLabel"] = QtGui.QLabel("<b>Enable Mask Estim.:</b>")
widgets["horusMaskEstimatorSelector"] = QtGui.QCheckBox()
widgets["horusMaskEstimatorSelector"].setToolTip(
"Enable the mask frequency estimator, which makes uses of the \n"\
"tone spacing value entered below as extra input to the frequency\n"\
"estimator. This can help decode performance in very weak signal conditions."
)
widgets["horusMaskSpacingLabel"] = QtGui.QLabel("<b>Tone Spacing (Hz):</b>")
widgets["horusMaskSpacingEntry"] = QtGui.QLineEdit("270")
widgets["horusMaskSpacingEntry"].setToolTip(
"If the tone spacing of the transmitter is known, it can be entered here,\n"\
"and used with the mask estimator option above. The default tone spacing for\n"\
"a RS41-based transmitter is 270 Hz."
)
widgets["horusManualEstimatorLabel"] = QtGui.QLabel("<b>Manual Estim. Limits:</b>")
widgets["horusManualEstimatorSelector"] = QtGui.QCheckBox()
widgets["horusManualEstimatorSelector"].setToolTip(
"Enables manual selection of the frequency estimator limits. This will enable\n"\
"a slidable area on the spectrum display, which can be used to select the frequency\n"\
"range of interest, and help stop in-band CW interference from biasing the frequency\n"\
"estimator. You can either click-and-drag the entire area, or click-and-drag the edges\n"\
"to change the estimator frequency range."
)
# Start/Stop
widgets["startDecodeButton"] = QtGui.QPushButton("Start")
@ -168,14 +187,30 @@ widgets["habitatUploadSelector"].setChecked(True)
widgets["userCallLabel"] = QtGui.QLabel("<b>Callsign:</b>")
widgets["userCallEntry"] = QtGui.QLineEdit("N0CALL")
widgets["userCallEntry"].setMaxLength(20)
widgets["userCallEntry"].setToolTip(
"Your station callsign, which doesn't necessarily need to be an\n"\
"amateur radio callsign."
)
widgets["userLocationLabel"] = QtGui.QLabel("<b>Lat/Lon:</b>")
widgets["userLatEntry"] = QtGui.QLineEdit("0.0")
widgets["userLatEntry"].setToolTip("Station Latitude in Decimal Degrees, e.g. -34.123456")
widgets["userLonEntry"] = QtGui.QLineEdit("0.0")
widgets["userLonEntry"].setToolTip("Station Longitude in Decimal Degrees, e.g. 138.123456")
widgets["userAntennaLabel"] = QtGui.QLabel("<b>Antenna:</b>")
widgets["userAntennaEntry"] = QtGui.QLineEdit("")
widgets["userAntennaEntry"].setToolTip("A text description of your station's antenna.")
widgets["userRadioLabel"] = QtGui.QLabel("<b>Radio:</b>")
widgets["userRadioEntry"] = QtGui.QLineEdit("Horus-GUI " + __version__)
widgets["userRadioEntry"].setToolTip(
"A text description of your station's radio setup.\n"\
"This field will be automatically prefixed with Horus-GUI."
)
widgets["habitatUploadPosition"] = QtGui.QPushButton("Upload Position")
widgets["habitatUploadPosition"].setToolTip(
"Manually re-upload your position information to HabHub.\n"\
"Note that it can take a few minutes for your new information to\n"\
"appear on the map."
)
widgets["saveSettingsButton"] = QtGui.QPushButton("Save Settings")
w1_habitat.addWidget(widgets["habitatUploadLabel"], 0, 0, 1, 1)
@ -199,14 +234,38 @@ w1_other = pg.LayoutWidget()
widgets["horusUploadLabel"] = QtGui.QLabel("<b>Enable Horus UDP Output:</b>")
widgets["horusUploadSelector"] = QtGui.QCheckBox()
widgets["horusUploadSelector"].setChecked(True)
widgets["horusUploadSelector"].setToolTip(
"Enable output of 'Horus UDP' JSON messages. These are emitted as a JSON object\n"\
"and contain the fields: callsign, time, latitude, longitude, altitude, snr"\
)
widgets["horusUDPLabel"] = QtGui.QLabel("<b>Horus UDP Port:</b>")
widgets["horusUDPEntry"] = QtGui.QLineEdit("55672")
widgets["horusUDPEntry"].setMaxLength(5)
widgets["horusUDPEntry"].setToolTip(
"UDP Port to output 'Horus UDP' JSON messages to."
)
widgets["ozimuxUploadLabel"] = QtGui.QLabel("<b>Enable OziMux UDP Output:</b>")
widgets["ozimuxUploadSelector"] = QtGui.QCheckBox()
widgets["ozimuxUploadSelector"].setChecked(False)
widgets["ozimuxUploadSelector"].setToolTip(
"Output OziMux UDP messages. These are of the form:\n"\
"'TELEMETRY,HH:MM:SS,lat,lon,alt\\n'"
)
widgets["ozimuxUDPLabel"] = QtGui.QLabel("<b>Ozimux UDP Port:</b>")
widgets["ozimuxUDPEntry"] = QtGui.QLineEdit("55683")
widgets["ozimuxUDPEntry"].setMaxLength(5)
widgets["ozimuxUDPEntry"].setToolTip(
"UDP Port to output 'OziMux' UDP messages to."
)
w1_other.addWidget(widgets["horusUploadLabel"], 0, 0, 1, 1)
w1_other.addWidget(widgets["horusUploadSelector"], 0, 1, 1, 1)
w1_other.addWidget(widgets["horusUDPLabel"], 1, 0, 1, 1)
w1_other.addWidget(widgets["horusUDPEntry"], 1, 1, 1, 1)
w1_other.addWidget(widgets["ozimuxUploadLabel"], 2, 0, 1, 1)
w1_other.addWidget(widgets["ozimuxUploadSelector"], 2, 1, 1, 1)
w1_other.addWidget(widgets["ozimuxUDPLabel"], 3, 0, 1, 1)
w1_other.addWidget(widgets["ozimuxUDPEntry"], 3, 1, 1, 1)
w1_other.layout.setRowStretch(5, 1)
d0_other.addWidget(w1_other)
@ -308,13 +367,9 @@ w4_data = pg.LayoutWidget()
widgets["latestRawSentenceLabel"] = QtGui.QLabel("<b>Latest Packet (Raw):</b>")
widgets["latestRawSentenceData"] = QtGui.QLineEdit("NO DATA")
widgets["latestRawSentenceData"].setReadOnly(True)
#widgets["latestRawSentenceData"].setFont(QtGui.QFont("Courier New", 18, QtGui.QFont.Bold))
#widgets["latestRawSentenceData"].setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
widgets["latestDecodedSentenceLabel"] = QtGui.QLabel("<b>Latest Packet (Decoded):</b>")
widgets["latestDecodedSentenceData"] = QtGui.QLineEdit("NO DATA")
widgets["latestDecodedSentenceData"].setReadOnly(True)
#widgets["latestDecodedSentenceData"].setFont(QtGui.QFont("Courier New", 18, QtGui.QFont.Bold))
#widgets["latestDecodedSentenceData"].setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
w4_data.addWidget(widgets["latestRawSentenceLabel"], 0, 0, 1, 1)
w4_data.addWidget(widgets["latestRawSentenceData"], 0, 1, 1, 6)
w4_data.addWidget(widgets["latestDecodedSentenceLabel"], 1, 0, 1, 1)
@ -322,7 +377,12 @@ w4_data.addWidget(widgets["latestDecodedSentenceData"], 1, 1, 1, 6)
d3_data.addWidget(w4_data)
w4_position = pg.LayoutWidget()
POSITION_LABEL_FONT_SIZE = 16
# This font seems to look bigger in Windows... not sure why.
if 'Windows' in platform.system():
POSITION_LABEL_FONT_SIZE = 14
else:
POSITION_LABEL_FONT_SIZE = 16
widgets["latestPacketCallsignLabel"] = QtGui.QLabel("<b>Callsign</b>")
widgets["latestPacketCallsignValue"] = QtGui.QLabel("---")
widgets["latestPacketCallsignValue"].setFont(QtGui.QFont("Courier New", POSITION_LABEL_FONT_SIZE, QtGui.QFont.Bold))
@ -641,6 +701,11 @@ def handle_new_packet(frame):
_decoded['snr'] = _snr
send_payload_summary(_decoded, port=_udp_port)
# Send data out via OziMux messaging
if widgets["ozimuxUploadSelector"].isChecked():
_udp_port = int(widgets["ozimuxUDPEntry"].text())
send_ozimux_message(_decoded, port=_udp_port)
@ -743,6 +808,14 @@ def start_decoding():
running = True
logging.info("Started Audio Processing.")
# Grey out some selectors, so the user cannot adjust them while we are decoding.
widgets["audioDeviceSelector"].setEnabled(False)
widgets["audioSampleRateSelector"].setEnabled(False)
widgets["horusModemSelector"].setEnabled(False)
widgets["horusModemRateSelector"].setEnabled(False)
widgets["horusMaskEstimatorSelector"].setEnabled(False) # This should really be editable while running.
widgets["horusMaskSpacingEntry"].setEnabled(False) # This should really be editable while running
else:
try:
audio_stream.stop()
@ -768,6 +841,14 @@ def start_decoding():
running = False
logging.info("Stopped Audio Processing.")
# Re-Activate selectors.
widgets["audioDeviceSelector"].setEnabled(True)
widgets["audioSampleRateSelector"].setEnabled(True)
widgets["horusModemSelector"].setEnabled(True)
widgets["horusModemRateSelector"].setEnabled(True)
widgets["horusMaskEstimatorSelector"].setEnabled(True)
widgets["horusMaskSpacingEntry"].setEnabled(True)
widgets["startDecodeButton"].clicked.connect(start_decoding)

Wyświetl plik

@ -7,7 +7,7 @@ from horusdemodlib.demod import Mode
HORUS_MODEM_LIST = {
"Horus Binary v1 (Legacy)": {
"id": Mode.BINARY_V1,
"baud_rates": [25, 50, 100, 300],
"baud_rates": [50, 100, 300], # Note: 25 Baud removed until issues in underlying modem are fixed.
"default_baud_rate": 100,
"default_tone_spacing": 270,
"use_mask_estimator": False,

Wyświetl plik

@ -1,6 +1,6 @@
[tool.poetry]
name = "horusgui"
version = "0.1.12"
version = "0.1.14"
description = ""
authors = ["Mark Jessop <vk5qi@rfhead.net>"]
@ -12,7 +12,7 @@ PyQt5 = "^5.13.0"
pyqtgraph = "^0.11.0"
pyaudio = "^0.2.11"
"ruamel.yaml" = "^0.16.10"
horusdemodlib = "^0.1.1"
horusdemodlib = "^0.1.19"
[tool.poetry.dev-dependencies]

Wyświetl plik

@ -5,4 +5,4 @@ PyQt5
pyqtgraph
ruamel.yaml
requests
horusdemodlib
horusdemodlib>=0.1.20