first version with freedata explorer

This commit is contained in:
dj2ls 2022-11-05 22:27:33 +01:00
parent a69badc88c
commit 826a39ca4d
11 changed files with 202 additions and 9 deletions

View file

@ -217,7 +217,7 @@ exports.getDaemonState = function() {
// START TNC
// ` `== multi line string
exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, devicename, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port, enable_fft, enable_scatter, low_bandwidth_mode, tuning_range_fmin, tuning_range_fmax, enable_fsk, tx_audio_level, respond_to_cq, rx_buffer_size) {
exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, devicename, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port, enable_fft, enable_scatter, low_bandwidth_mode, tuning_range_fmin, tuning_range_fmax, enable_fsk, tx_audio_level, respond_to_cq, rx_buffer_size, enable_explorer) {
var json_command = JSON.stringify({
type: 'set',
command: 'start_tnc',
@ -245,7 +245,8 @@ exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, de
tuning_range_fmax : tuning_range_fmax,
tx_audio_level : tx_audio_level,
respond_to_cq : respond_to_cq,
rx_buffer_size : rx_buffer_size
rx_buffer_size : rx_buffer_size,
enable_explorer : enable_explorer
}]
})

View file

@ -90,7 +90,8 @@ const configDefaultSettings = '{\
"tuning_range_fmin" : "-50.0",\
"tuning_range_fmax" : "50.0",\
"respond_to_cq" : "True",\
"rx_buffer_size" : "16" \
"rx_buffer_size" : "16", \
"enable_explorer" : "False" \
}';
if (!fs.existsSync(configPath)) {

View file

@ -160,7 +160,13 @@ set_setting_switch("enable_hamlib_ptt_port", "hamlib_ptt_port", config.enable_ha
document.getElementById("respondCQSwitch").checked = true;
} else {
document.getElementById("respondCQSwitch").checked = false;
}
}
if(config.enable_explorer == 'True'){
document.getElementById("ExplorerSwitch").checked = true;
} else {
document.getElementById("ExplorerSwitch").checked = false;
}
// theme selector
if(config.theme != 'default'){
@ -872,7 +878,16 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
}
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
});
// enable explorer Switch clicked
document.getElementById("ExplorerSwitch").addEventListener("click", () => {
if(document.getElementById("ExplorerSwitch").checked == true){
config.enable_explorer = "True";
} else {
config.enable_explorer = "False";
}
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
});
// enable fsk Switch clicked
document.getElementById("fskModeSwitch").addEventListener("click", () => {
@ -1008,6 +1023,11 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
var respond_to_cq = "False";
}
if (document.getElementById("ExplorerSwitch").checked == true){
var enable_explorer = "True";
} else {
var enable_explorer = "False";
}
// loop through audio device list and select
for(i = 0; i < document.getElementById("audio_input_selectbox").length; i++) {
@ -1067,6 +1087,7 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
config.tx_audio_level = tx_audio_level;
config.respond_to_cq = respond_to_cq;
config.rx_buffer_size = rx_buffer_size;
config.enable_explorer = enable_explorer;
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
@ -1085,7 +1106,7 @@ document.getElementById('hamlib_rigctld_stop').addEventListener('click', () => {
*/
daemon.startTNC(callsign_ssid, mygrid, rx_audio, tx_audio, radiocontrol, deviceid, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port, enable_fft, enable_scatter, low_bandwidth_mode, tuning_range_fmin, tuning_range_fmax, enable_fsk, tx_audio_level, respond_to_cq, rx_buffer_size);
daemon.startTNC(callsign_ssid, mygrid, rx_audio, tx_audio, radiocontrol, deviceid, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port, enable_fft, enable_scatter, low_bandwidth_mode, tuning_range_fmin, tuning_range_fmax, enable_fsk, tx_audio_level, respond_to_cq, rx_buffer_size, enable_explorer);
})

View file

@ -1204,6 +1204,15 @@
</div>
</label>
</div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Enable Explorer Publishing</label>
<label class="input-group-text bg-white w-50">
<div class="form-check form-switch form-check-inline">
<input class="form-check-input" type="checkbox" id="ExplorerSwitch">
<label class="form-check-label" for="ExplorerSwitch">Publish</label>
</div>
</label>
</div>
<div class="input-group input-group-sm mb-1">
<label class="input-group-text w-50">Respond to CQ</label>
<label class="input-group-text bg-white w-50">

View file

@ -74,7 +74,8 @@ class CONFIG:
'fmin': data[19],
'fmax': data[20],
'qrv': data[23],
'rxbuffersize': data[24]
'rxbuffersize': data[24],
'explorer': data[25]
}
try:
with open(self.config_name, 'w') as configfile:

View file

@ -248,6 +248,9 @@ class DAEMON:
options.append("--rx-buffer-size")
options.append(data[24])
if data[25] == "True":
options.append("--explorer")
# safe data to config file
config.write_entire_config(data)

57
tnc/explorer.py Normal file
View file

@ -0,0 +1,57 @@
# -*- coding: UTF-8 -*-
"""
Created on 05.11.23
@author: DJ2LS
"""
# pylint: disable=invalid-name, line-too-long, c-extension-no-member
# pylint: disable=import-outside-toplevel, attribute-defined-outside-init
import requests
import threading
import time
import ujson as json
import structlog
import static
log = structlog.get_logger("explorer")
class explorer():
def __init__(self):
self.explorer_url = "https://explorer.freedata.app/api.php"
self.publish_interval = 3
self.interval_thread = threading.Thread(target=self.interval, name="interval", daemon=True)
self.interval_thread.start()
def interval(self):
while True:
self.push()
time.sleep(self.publish_interval)
def push(self):
if static.HAMLIB_FREQUENCY is not None:
frequency = static.HAMLIB_FREQUENCY
else:
frequency = 0
band = "USB"
callsign = str(static.MYCALLSIGN, "utf-8")
gridsquare = str(static.MYGRID, "utf-8")
version = str(static.VERSION)
bandwidth = str(static.LOW_BANDWIDTH_MODE)
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)
headers = {"Content-Type": "application/json"}
station_data = {'callsign': callsign, 'gridsquare': gridsquare, 'frequency': frequency, 'band': band, 'version': version, 'bandwidth': bandwidth}
station_data = json.dumps(station_data)
try:
response = requests.post(self.explorer_url, json=station_data, headers=headers)
# print(response.status_code)
# print(response.content)
except Exception as e:
log.warning("[EXPLORER] connection lost")

View file

@ -7,6 +7,14 @@ Created on Tue Dec 22 16:58:45 2020
main module for running the tnc
"""
# run tnc self test on startup before we are doing other things
import selftest
selftest.TEST()
# continue if we passed the test
import argparse
import multiprocessing
import os
@ -22,10 +30,10 @@ import log_handler
import modem
import static
import structlog
import explorer
log = structlog.get_logger("main")
def signal_handler(sig, frame):
"""
a signal handler, which closes the network/socket when closing the application
@ -246,7 +254,12 @@ if __name__ == "__main__":
help="Set the maximum size of rx buffer.",
type=int,
)
PARSER.add_argument(
"--explorer",
dest="enable_explorer",
action="store_true",
help="Enable sending tnc data to https://explorer.freedata.app",
)
ARGS = PARSER.parse_args()
if ARGS.configfile:
# init config
@ -285,6 +298,7 @@ if __name__ == "__main__":
static.TX_AUDIO_LEVEL = config['AUDIO']['txaudiolevel']
static.RESPOND_TO_CQ = config['TNC']['qrv']
static.RX_BUFFER_SIZE = config['TNC']['rxbuffersize']
static.ENABLE_EXPLORER = config['TNC']['explorer']
else:
@ -321,6 +335,7 @@ if __name__ == "__main__":
static.TX_AUDIO_LEVEL = ARGS.tx_audio_level
static.RESPOND_TO_CQ = ARGS.enable_respond_to_cq
static.RX_BUFFER_SIZE = ARGS.rx_buffer_size
static.ENABLE_EXPLORER = ARGS.enable_explorer
# we need to wait until we got all parameters from argparse first before we can load the other modules
import sock
@ -358,6 +373,12 @@ if __name__ == "__main__":
# start modem
modem = modem.RF()
# start explorer
print(static.ENABLE_EXPLORER)
if static.ENABLE_EXPLORER:
log.info("[EXPLORER] Publishing to https://explorer.freedata.app", state=static.ENABLE_EXPLORER)
explorer = explorer.explorer()
# --------------------------------------------START CMD SERVER
try:
log.info("[TNC] Starting TCP/IP socket", port=static.PORT)

74
tnc/selftest.py Normal file
View file

@ -0,0 +1,74 @@
"""
simple TNC self tests
"""
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name, line-too-long, c-extension-no-member
# pylint: disable=import-outside-toplevel, attribute-defined-outside-init
import sys
import structlog
log = structlog.get_logger("selftest")
class TEST():
def __init__(self):
log.info("[selftest] running self tests...")
if self.run_tests():
log.info("[selftest] passed -> starting TNC")
else:
log.error("[selftest] failed -> closing TNC")
sys.exit(0)
def run_tests(self):
return bool(
self.check_imports()
and self.check_sounddevice()
and self.check_helpers()
)
def check_imports(self):
try:
import argparse
import atexit
import multiprocessing
import os
import signal
import socketserver
import sys
import threading
import time
import structlog
import crcengine
import ctypes
import glob
import enum
import numpy
import sounddevice
return True
except Exception as e:
log.info("[selftest] [check_imports] [failed]", e=e)
return False
def check_sounddevice(self):
try:
import audio
audio.get_audio_devices()
return True
except Exception as e:
log.info("[selftest] [check_sounddevice] [failed]", e=e)
return False
def check_helpers(self):
try:
import helpers
valid_crc24 = "f86ed0"
if helpers.get_crc_24(b"test").hex() == valid_crc24:
return True
else:
raise Exception
except Exception as e:
log.info("[selftest] [check_helpers] [failed]", e=e)
return False

View file

@ -608,6 +608,7 @@ def process_daemon_commands(data):
tx_audio_level = str(received_json["parameter"][0]["tx_audio_level"])
respond_to_cq = str(received_json["parameter"][0]["respond_to_cq"])
rx_buffer_size = str(received_json["parameter"][0]["rx_buffer_size"])
enable_explorer = str(received_json["parameter"][0]["enable_explorer"])
# print some debugging parameters
for item in received_json["parameter"][0]:
@ -643,6 +644,7 @@ def process_daemon_commands(data):
tx_audio_level,
respond_to_cq,
rx_buffer_size,
enable_explorer,
]
)
command_response("start_tnc", True)

View file

@ -13,6 +13,9 @@ from enum import Enum
VERSION = "0.6.1-alpha.1"
ENABLE_EXPLORER = False
# DAEMON
DAEMONPORT: int = 3001
TNCSTARTED: bool = False