From 4ba1624766e0244dbdd73811a1a06bbf3e8873d4 Mon Sep 17 00:00:00 2001 From: LA3QMA Date: Thu, 23 Jan 2025 12:37:40 +0100 Subject: [PATCH 01/17] If there is no gridsquare fix this so that it follows the ADIF standard. --- freedata_server/adif_udp_logger.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/freedata_server/adif_udp_logger.py b/freedata_server/adif_udp_logger.py index e0e96b74..2c968f46 100644 --- a/freedata_server/adif_udp_logger.py +++ b/freedata_server/adif_udp_logger.py @@ -1,5 +1,5 @@ import socket - +import re def send_adif_qso_data(config, adif_data): @@ -16,6 +16,11 @@ def send_adif_qso_data(config, adif_data): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: + + # If there is no gridsquare fix this so that it follows the ADIF standard. + #FIXME this check should probably be in message_system_db_station/model.py so this should be considered as a quick fix + adif_data = re.sub(r"----", "", adif_data) + # Send the ADIF data to the server sock.sendto(adif_data.encode('utf-8'), (adif_log_host, adif_log_port)) print(f"ADIF QSO data sent to {adif_log_host}:{adif_log_port}", adif_data.encode('utf-8')) From dce5cc7dd70757307f2d5b043a3f1aba5711a870 Mon Sep 17 00:00:00 2001 From: LA3QMA Date: Fri, 24 Jan 2025 09:41:11 +0100 Subject: [PATCH 02/17] Added support for Wavelog --- freedata_gui/src/components/settings_chat.vue | 44 +++++++++++++++++++ freedata_server/config.ini.example | 2 + freedata_server/config.py | 2 + freedata_server/server.py | 2 + freedata_server/wavelog_api_logger.py | 38 ++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 freedata_server/wavelog_api_logger.py diff --git a/freedata_gui/src/components/settings_chat.vue b/freedata_gui/src/components/settings_chat.vue index d910a8e0..e483d4f2 100644 --- a/freedata_gui/src/components/settings_chat.vue +++ b/freedata_gui/src/components/settings_chat.vue @@ -99,5 +99,49 @@ export default { v-model.number="settings.remote.MESSAGES.adif_log_port" /> + +
+ + +
+ +
+ + +
diff --git a/freedata_server/config.ini.example b/freedata_server/config.ini.example index ce4a17aa..40cae15d 100644 --- a/freedata_server/config.ini.example +++ b/freedata_server/config.ini.example @@ -65,6 +65,8 @@ data_port = 8001 enable_auto_repeat = False adif_log_host = 127.0.0.1 adif_log_port = 2237 +wavelog_host = http://localhost:8086 +wavelog_api_key = 0 [GUI] auto_run_browser = True diff --git a/freedata_server/config.py b/freedata_server/config.py index 189cb6dd..b40101c0 100644 --- a/freedata_server/config.py +++ b/freedata_server/config.py @@ -78,6 +78,8 @@ class CONFIG: 'enable_auto_repeat': bool, 'adif_log_host': str, 'adif_log_port': int, + 'wavelog_host': str, + 'wavelog_api_key': str, }, 'GUI':{ 'auto_run_browser': bool, diff --git a/freedata_server/server.py b/freedata_server/server.py index fc435fbb..30d3ded8 100644 --- a/freedata_server/server.py +++ b/freedata_server/server.py @@ -35,6 +35,7 @@ import event_manager import structlog from log_handler import setup_logging import adif_udp_logger +import wavelog_api_logger from message_system_db_manager import DatabaseManager from message_system_db_messages import DatabaseManagerMessages @@ -1673,6 +1674,7 @@ async def post_freedata_message_adif_log(message_id: str): adif_output = DatabaseManagerMessages(app.event_manager).get_message_by_id_adif(message_id) # Send the ADIF data via UDP adif_udp_logger.send_adif_qso_data(app.config_manager.read(), adif_output) + wavelog_api_logger.send_wavelog_qso_data(app.config_manager.read(), adif_output) return api_response(adif_output) @app.patch("/freedata/messages/{message_id}", summary="Update Message by ID", tags=["FreeDATA"], responses={ diff --git a/freedata_server/wavelog_api_logger.py b/freedata_server/wavelog_api_logger.py new file mode 100644 index 00000000..ca1cf1c3 --- /dev/null +++ b/freedata_server/wavelog_api_logger.py @@ -0,0 +1,38 @@ +import requests +import re + + +def send_wavelog_qso_data(config, wavelog_data): + """ + Sends wavelog QSO data to the specified server via API call. + + Parameters: + server_host:port (str) + server_api_key (str) + wavelog_data (str): wavelog-formatted ADIF QSO data. + """ + wavelog_host = config['MESSAGES'].get('wavelog_host', 'http://localhost:8086') + wavelog_api_key = config['MESSAGES'].get('wavelog_api_key', '') + + url = wavelog_host + "/index.php/api/qso" + headers = { + "Content-Type": "application/json", + "Accept": "application/json" + } + + # If there is no gridsquare fix this so that it follows the ADIF standard. + wavelog_data = re.sub(r"----", "", wavelog_data) + + data = { + "key": wavelog_api_key, + "station_profile_id": "1", + "type": "adif", + "string": wavelog_data + } + + try: + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() # Raise an error for bad status codes + print("Response:", response.json()) # Print the JSON response from the server + except requests.exceptions.RequestException as e: + print("An error occurred:", e) From 5b2cd3ca4cf831d2722650863d98befa55752f72 Mon Sep 17 00:00:00 2001 From: LA3QMA Date: Sat, 25 Jan 2025 09:13:06 +0100 Subject: [PATCH 03/17] added function to enable/disable adif/wavelog. test for more grids that are formated wrong --- freedata_gui/src/components/settings_chat.vue | 55 +++++++++++++++++++ freedata_server/adif_udp_logger.py | 7 +++ freedata_server/config.ini.example | 2 + freedata_server/config.py | 2 + freedata_server/wavelog_api_logger.py | 20 ++++++- 5 files changed, 85 insertions(+), 1 deletion(-) diff --git a/freedata_gui/src/components/settings_chat.vue b/freedata_gui/src/components/settings_chat.vue index e483d4f2..a91cc0a3 100644 --- a/freedata_gui/src/components/settings_chat.vue +++ b/freedata_gui/src/components/settings_chat.vue @@ -52,6 +52,33 @@ export default { + +
+ + +
+
+ + +
+ + +
+
@@ -98,7 +98,7 @@ export default { placeholder="Enter ADIF server host" id="adifLogHost" @change="onChange" - v-model="settings.remote.MESSAGES.adif_log_host" + v-model="settings.remote.QSO_LOGGING.adif_udp_host" /> @@ -123,7 +123,7 @@ export default { max="65534" min="1025" @change="onChange" - v-model.number="settings.remote.MESSAGES.adif_log_port" + v-model.number="settings.remote.QSO_LOGGING.adif_udp_port" /> @@ -147,7 +147,7 @@ export default { type="checkbox" id="enableWavelogSwitch" @change="onChange" - v-model="settings.remote.MESSAGES.wavelog_enable" + v-model="settings.remote.QSO_LOGGING.enable_adif_wavelog" /> @@ -162,7 +162,7 @@ export default { type="button" class="btn btn-link p-0 ms-2" data-bs-toggle="tooltip" - title="Wavelog API server host, e.g., 127.0.0.1:8086" + title="Wavelog API server host, e.g., 127.0.0.1" > @@ -173,10 +173,33 @@ export default { placeholder="Enter wavelog server host" id="wavelogHost" @change="onChange" - v-model="settings.remote.MESSAGES.wavelog_host" + v-model="settings.remote.QSO_LOGGING.adif_wavelog_host" + /> + + +
+ +
-
diff --git a/freedata_server/adif_udp_logger.py b/freedata_server/adif_udp_logger.py index 4471c6a0..fe858e00 100644 --- a/freedata_server/adif_udp_logger.py +++ b/freedata_server/adif_udp_logger.py @@ -13,13 +13,13 @@ def send_adif_qso_data(config, adif_data): """ # If False then exit the function - adif = config['LOG_QSO'].get('enable_adif', 'False') + adif = config['QSO_LOGGING'].get('enable_adif_udp', 'False') if not adif: return # exit as we don't want to log ADIF UDP - adif_log_host = config['LOG_QSO'].get('adif_log_host', '127.0.0.1') - adif_log_port = int(config['LOG_QSO'].get('adif_log_port', '2237')) + adif_log_host = config['QSO_LOGGING'].get('adif_udp_host', '127.0.0.1') + adif_log_port = int(config['QSO_LOGGING'].get('adif_udp_port', '2237')) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: diff --git a/freedata_server/config.ini.example b/freedata_server/config.ini.example index d2581f3f..063f03ac 100644 --- a/freedata_server/config.ini.example +++ b/freedata_server/config.ini.example @@ -64,13 +64,14 @@ data_port = 8001 [MESSAGES] enable_auto_repeat = False -[LOG_QSO] -enable_adif = False -adif_log_host = 127.0.0.1 -adif_log_port = 2237 -wavelog_enable = False -wavelog_host = http://raspberrypi:8086 -wavelog_api_key = wl6793ce6c78c21 +[QSO_LOGGING] +enable_adif_udp = False +adif_udp_host = 127.0.0.1 +adif_udp_port = 2237 +enable_adif_wavelog = False +adif_wavelog_host = http://raspberrypi +adif_wavelog_port = 8086 +adif_wavelog_api_key = wl6793ce6c78c21 [GUI] auto_run_browser = True diff --git a/freedata_server/config.py b/freedata_server/config.py index 73ef9bfb..72c26a78 100644 --- a/freedata_server/config.py +++ b/freedata_server/config.py @@ -83,13 +83,14 @@ class CONFIG: 'wavelog_host': str, 'wavelog_api_key': str, }, - 'LOG_QSO': { - 'enable_adif': bool, - 'adif_log_host': str, - 'adif_log_port': int, - 'wavelog_enable': bool, - 'wavelog_host': str, - 'wavelog_api_key': str, + 'QSO_LOGGING': { + 'enable_adif_udp': bool, + 'adif_udp_host': str, + 'adif_udp_port': int, + 'enable_adif_wavelog': bool, + 'adif_wavelog_host': str, + 'adif_wavelog_port': int, + 'adif_wavelog_api_key': str, }, 'GUI': { diff --git a/freedata_server/wavelog_api_logger.py b/freedata_server/wavelog_api_logger.py index 88e98808..2e648d5d 100644 --- a/freedata_server/wavelog_api_logger.py +++ b/freedata_server/wavelog_api_logger.py @@ -13,15 +13,17 @@ def send_wavelog_qso_data(config, wavelog_data): """ # If False then exit the function - wavelog = config['LOG_QSO'].get('wavelog_enable', 'False') + wavelog = config['QSO_LOGGING'].get('enable_adif_wavelog', 'False') if not wavelog: return # exit as we don't want to log Wavelog - wavelog_host = config['LOG_QSO'].get('wavelog_host', 'http://localhost:8086') - wavelog_api_key = config['LOG_QSO'].get('wavelog_api_key', '') + wavelog_host = config['QSO_LOGGING'].get('adif_wavelog_host', 'http://localhost') + wavelog_port = config['QSO_LOGGING'].get('adif_wavelog_port', '8086') + wavelog_api_key = config['QSO_LOGGING'].get('adif_wavelog_api_key', '') + + url = wavelog_host + ":" + str(wavelog_port) + "/index.php/api/qso" - url = wavelog_host + "/index.php/api/qso" headers = { "Content-Type": "application/json", "Accept": "application/json" From 78138c641904477bffe70fde708d114cbef6200a Mon Sep 17 00:00:00 2001 From: LA3QMA Date: Sun, 26 Jan 2025 14:49:07 +0100 Subject: [PATCH 08/17] Cleaned up print/log. Started to get better gridsquare handling --- freedata_server/adif_udp_logger.py | 7 +++++-- freedata_server/config.ini.example | 2 +- freedata_server/config.py | 6 ------ freedata_server/message_system_db_messages.py | 4 ++-- freedata_server/wavelog_api_logger.py | 9 +++++---- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/freedata_server/adif_udp_logger.py b/freedata_server/adif_udp_logger.py index fe858e00..1a85119d 100644 --- a/freedata_server/adif_udp_logger.py +++ b/freedata_server/adif_udp_logger.py @@ -1,5 +1,6 @@ import socket import re +import structlog def send_adif_qso_data(config, adif_data): @@ -12,6 +13,8 @@ def send_adif_qso_data(config, adif_data): adif_data (str): ADIF-formatted QSO data. """ + log = structlog.get_logger() + # If False then exit the function adif = config['QSO_LOGGING'].get('enable_adif_udp', 'False') @@ -31,8 +34,8 @@ def send_adif_qso_data(config, adif_data): # Send the ADIF data to the server sock.sendto(adif_data.encode('utf-8'), (adif_log_host, adif_log_port)) - print(f"ADIF QSO data sent to {adif_log_host}:{adif_log_port}", adif_data.encode('utf-8')) + log.info(f"[CHAT] ADIF QSO data sent to: {adif_log_host}:{adif_log_port} {adif_data.encode('utf-8')}") except Exception as e: - print(f"Error sending ADIF data: {e}") + log.info(f"[CHAT] Error sending ADIF data: {e}") finally: sock.close() diff --git a/freedata_server/config.ini.example b/freedata_server/config.ini.example index 063f03ac..89381819 100644 --- a/freedata_server/config.ini.example +++ b/freedata_server/config.ini.example @@ -71,7 +71,7 @@ adif_udp_port = 2237 enable_adif_wavelog = False adif_wavelog_host = http://raspberrypi adif_wavelog_port = 8086 -adif_wavelog_api_key = wl6793ce6c78c21 +adif_wavelog_api_key = API-KEY [GUI] auto_run_browser = True diff --git a/freedata_server/config.py b/freedata_server/config.py index 72c26a78..d44ba62c 100644 --- a/freedata_server/config.py +++ b/freedata_server/config.py @@ -76,12 +76,6 @@ class CONFIG: }, 'MESSAGES': { 'enable_auto_repeat': bool, - 'enable_adif': bool, - 'adif_log_host': str, - 'adif_log_port': int, - 'wavelog_enable': bool, - 'wavelog_host': str, - 'wavelog_api_key': str, }, 'QSO_LOGGING': { 'enable_adif_udp': bool, diff --git a/freedata_server/message_system_db_messages.py b/freedata_server/message_system_db_messages.py index 958ed6d3..e922c806 100644 --- a/freedata_server/message_system_db_messages.py +++ b/freedata_server/message_system_db_messages.py @@ -181,9 +181,9 @@ class DatabaseManagerMessages(DatabaseManager): print(origin_info) if origin_info and "location" in origin_info and origin_info["location"] is not None: print(origin_info["location"]) - grid = origin_info["location"].get("gridsquare", "----") + grid = origin_info["location"].get("gridsquare", "") else: - grid = "----" + grid = "" # Extract and adjust the frequency (Hz to MHz) diff --git a/freedata_server/wavelog_api_logger.py b/freedata_server/wavelog_api_logger.py index 2e648d5d..065377ed 100644 --- a/freedata_server/wavelog_api_logger.py +++ b/freedata_server/wavelog_api_logger.py @@ -1,6 +1,6 @@ import requests import re - +import structlog def send_wavelog_qso_data(config, wavelog_data): """ @@ -12,6 +12,8 @@ def send_wavelog_qso_data(config, wavelog_data): wavelog_data (str): wavelog-formatted ADIF QSO data. """ + log = structlog.get_logger() + # If False then exit the function wavelog = config['QSO_LOGGING'].get('enable_adif_wavelog', 'False') @@ -41,7 +43,6 @@ def send_wavelog_qso_data(config, wavelog_data): wavelog_data = re.sub(grids, "", wavelog_data) break -# wavelog_data = re.sub(r"----", "", wavelog_data) data = { "key": wavelog_api_key, @@ -53,6 +54,6 @@ def send_wavelog_qso_data(config, wavelog_data): try: response = requests.post(url, headers=headers, json=data) response.raise_for_status() # Raise an error for bad status codes - print("Response:", response.json()) # Print the JSON response from the server + log.info(f"[CHAT] Error Wavelog API: {response.json()}") except requests.exceptions.RequestException as e: - print("An error occurred:", e) + log.warning(f"[WAVELOG ADIF API EXCEPTION]: {e}") From aadb7c00d0a84c4faca02908463bcee9dd7882a3 Mon Sep 17 00:00:00 2001 From: LA3QMA Date: Mon, 27 Jan 2025 14:06:13 +0100 Subject: [PATCH 09/17] Removed unused code. Fixed so that ADIF is only posted to UDP/API if there is a valid gridsquare. --- freedata_server/adif_udp_logger.py | 5 ----- freedata_server/server.py | 5 +++++ freedata_server/wavelog_api_logger.py | 15 +-------------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/freedata_server/adif_udp_logger.py b/freedata_server/adif_udp_logger.py index 1a85119d..1f3f7840 100644 --- a/freedata_server/adif_udp_logger.py +++ b/freedata_server/adif_udp_logger.py @@ -27,11 +27,6 @@ def send_adif_qso_data(config, adif_data): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: - # If there is no gridsquare fix this so that it follows the ADIF standard. - # FIXME this check should probably be in message_system_db_station/model.py - # so this should be considered as a quick fix - adif_data = re.sub(r"----", "", adif_data) - # Send the ADIF data to the server sock.sendto(adif_data.encode('utf-8'), (adif_log_host, adif_log_port)) log.info(f"[CHAT] ADIF QSO data sent to: {adif_log_host}:{adif_log_port} {adif_data.encode('utf-8')}") diff --git a/freedata_server/server.py b/freedata_server/server.py index 30d3ded8..378ecfc6 100644 --- a/freedata_server/server.py +++ b/freedata_server/server.py @@ -1672,6 +1672,11 @@ async def post_freedata_message(request: Request): }) async def post_freedata_message_adif_log(message_id: str): adif_output = DatabaseManagerMessages(app.event_manager).get_message_by_id_adif(message_id) + + # if message not found do not send adif as the return then is not valid + if not adif_output: + return + # Send the ADIF data via UDP adif_udp_logger.send_adif_qso_data(app.config_manager.read(), adif_output) wavelog_api_logger.send_wavelog_qso_data(app.config_manager.read(), adif_output) diff --git a/freedata_server/wavelog_api_logger.py b/freedata_server/wavelog_api_logger.py index 065377ed..bb821d1d 100644 --- a/freedata_server/wavelog_api_logger.py +++ b/freedata_server/wavelog_api_logger.py @@ -31,19 +31,6 @@ def send_wavelog_qso_data(config, wavelog_data): "Accept": "application/json" } - # If there is no gridsquare fix this so that it follows the ADIF standard. - wrong_grids = [ - r"----", - r" ", - r"N/A" - ] - - for grids in wrong_grids: - if re.search(grids, wavelog_data): - wavelog_data = re.sub(grids, "", wavelog_data) - break - - data = { "key": wavelog_api_key, "station_profile_id": "1", @@ -54,6 +41,6 @@ def send_wavelog_qso_data(config, wavelog_data): try: response = requests.post(url, headers=headers, json=data) response.raise_for_status() # Raise an error for bad status codes - log.info(f"[CHAT] Error Wavelog API: {response.json()}") + log.info(f"[CHAT] Wavelog API: {wavelog_data}") except requests.exceptions.RequestException as e: log.warning(f"[WAVELOG ADIF API EXCEPTION]: {e}") From 96304768d49686cc054d94b31ff3fd3985ab1bd4 Mon Sep 17 00:00:00 2001 From: LA3QMA Date: Wed, 29 Jan 2025 10:26:58 +0100 Subject: [PATCH 10/17] Removed Wavelog port to follow documentaion/WIKI --- freedata_gui/src/components/settings_chat.vue | 24 ------------------- freedata_server/config.ini.example | 1 - freedata_server/config.py | 1 - freedata_server/wavelog_api_logger.py | 3 +-- 4 files changed, 1 insertion(+), 28 deletions(-) diff --git a/freedata_gui/src/components/settings_chat.vue b/freedata_gui/src/components/settings_chat.vue index e628fac1..7513f1a0 100644 --- a/freedata_gui/src/components/settings_chat.vue +++ b/freedata_gui/src/components/settings_chat.vue @@ -176,30 +176,6 @@ export default { v-model="settings.remote.QSO_LOGGING.adif_wavelog_host" /> - -
- - -