more cleanup

This commit is contained in:
DJ2LS 2023-11-12 23:22:53 +01:00
parent 3c8e77a237
commit 5962450be7
22 changed files with 117 additions and 118 deletions

View file

@ -16,12 +16,7 @@ import settings_exp from "./settings_exp.vue";
aria-labelledby="list-settings-list"
>
<div class="container">
<div class="badge text-bg-warning m-1">
<h5>
<i class="bi bi-exclamation-triangle"></i> Please restart the modem
after changing settings <i class="bi bi-exclamation-triangle"></i>
</h5>
</div>
<div class="card text-center">
<div class="card-header">

View file

@ -170,8 +170,7 @@ export function getModemConfigAsJSON() {
MESH: {
enable_protocol: settings.enable_mesh_features,
},
Modem: {
enable_explorer: settings.enable_explorer,
MODEM: {
enable_fft: settings.enable_fft,
tuning_range_fmax: settings.tuning_range_fmax,
tuning_range_fmin: settings.tuning_range_fmin,
@ -180,7 +179,6 @@ export function getModemConfigAsJSON() {
respond_to_cq: settings.respond_to_cq,
rx_buffer_size: settings.rx_buffer_size,
enable_scatter: "False",
enable_stats: settings.explorer_stats,
tx_delay: settings.tx_delay,
},
NETWORK: {
@ -195,6 +193,8 @@ export function getModemConfigAsJSON() {
mycall: settings.mycall + "-" + settings.myssid,
mygrid: settings.mygrid,
ssid_list: [],
enable_explorer: settings.enable_explorer,
enable_stats: settings.explorer_stats,
},
TCI: {
tci_ip: settings.tci_ip,

View file

@ -4,8 +4,6 @@ import helpers
import time
import modem
import base64
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, Statistics, TCIParam, Modem
import sock
import ujson as json
class broadcastHandler:
@ -13,7 +11,9 @@ class broadcastHandler:
log = structlog.get_logger("BROADCAST")
def __init__(self, event_queue) -> None:
def __init__(self, config, event_queue) -> None:
self.mycallsign = config['STATION']['mycall']
self.fec_wakeup_callsign = bytes()
self.longest_duration = 6
self.wakeup_received = False
@ -83,9 +83,7 @@ class broadcastHandler:
# and make sure we are not overwrite them if they exist
try:
if "mycallsign" not in jsondata:
jsondata["mycallsign"] = str(Station.mycallsign, "UTF-8")
if "dxcallsign" not in jsondata:
jsondata["dxcallsign"] = str(Station.dxcallsign, "UTF-8")
jsondata["mycallsign"] = str(self.mycallsign, "UTF-8")
except Exception as e:
self.log.debug("[Modem] error adding callsigns to network message", e=e)
@ -94,7 +92,6 @@ class broadcastHandler:
self.log.debug("[Modem] send_data_to_socket_queue:", jsondata=json_data_out)
# finally push data to our network queue
sock.SOCKET_QUEUE.put(json_data_out)
self.event_queue.put(json_data_out)
def watchdog(self):

View file

@ -2,13 +2,16 @@
modemport = 3000
[STATION]
mycall = DJ2LS-9
mygrid = JN49em
mycall = DJ2LS-5
mygrid = JN49en
ssid_list = []
enable_explorer = False
enable_stats = False
[AUDIO]
input_device = c07e
output_device = c07e
input_device = 4f55
output_device = 4f55
rx_audio_level = 0
tx_audio_level = 0
enable_auto_tune = False
@ -22,14 +25,11 @@ radioport = None
[TCI]
tci_ip = 127.0.0.1
tci_port = 50001
ip = 127.0.0.1
port = 50001
[MESH]
enable_protocol = False
[Modem]
enable_explorer = False
[MODEM]
enable_fft = True
tuning_range_fmax = 50
tuning_range_fmin = -50
@ -38,6 +38,5 @@ enable_low_bandwidth_mode = False
respond_to_cq = True
rx_buffer_size = 16
enable_scatter = False
enable_stats = False
tx_delay = 0

View file

@ -23,7 +23,7 @@ import codec2
import helpers
import modem
import numpy as np
import sock
import deprecated_sock
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, Statistics, TCIParam, Modem
import structlog
import stats
@ -41,7 +41,7 @@ class DATA:
log = structlog.get_logger("DATA")
def __init__(self, config, event_queue) -> None:
def __init__(self, config, event_queue, states) -> None:
self.stats = stats.stats()
self.event_queue = event_queue
@ -111,7 +111,7 @@ class DATA:
self.rx_n_frames_per_burst = 0
self.max_n_frames_per_burst = 1
self.broadcast = broadcast.broadcastHandler(self.event_queue)
self.broadcast = broadcast.broadcastHandler(config, self.event_queue)
# Flag to indicate if we received a low bandwidth mode channel opener
self.received_LOW_BANDWIDTH_MODE = False
@ -327,9 +327,9 @@ class DATA:
# [2] STATE bool
if data[2]:
self.beacon_interval = data[1]
Beacon.beacon_state = True
self.states.set("is_beacon_running", True)
else:
Beacon.beacon_state = False
self.states.set("is_beacon_running", False)
elif data[0] == "ARQ_RAW":
# [1] DATA_OUT bytes
@ -2772,7 +2772,7 @@ class DATA:
try:
while True:
threading.Event().wait(0.5)
while Beacon.beacon_state:
while self.states.is_beacon_runining:
if (
not ARQ.arq_session
and not self.arq_file_transfer
@ -2811,7 +2811,7 @@ class DATA:
self.beacon_interval_timer = time.time() + self.beacon_interval
while (
time.time() < self.beacon_interval_timer
and Beacon.beacon_state
and self.states.is_beacon_runining
and not Beacon.beacon_pause
):
threading.Event().wait(0.01)

View file

@ -25,7 +25,7 @@ import audio
import crcengine
import log_handler
import serial.tools.list_ports
import sock
import deprecated_sock
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, Statistics, TCIParam, Modem
import structlog
@ -544,7 +544,7 @@ class DAEMON:
elif sys.platform in ["win32", "win64"]:
command.append("python")
command.append("main.py")
command.append("deprecated_main.py")
command += options
proc = subprocess.Popen(command)
atexit.register(proc.kill)
@ -606,7 +606,7 @@ if __name__ == "__main__":
mainlog.info("[DMN] Starting TCP/IP socket", port=DAEMON.port)
# https://stackoverflow.com/a/16641793
socketserver.TCPServer.allow_reuse_address = True
cmdserver = sock.ThreadedTCPServer(
cmdserver = deprecated_sock.ThreadedTCPServer(
(Modem.host, DAEMON.port), sock.ThreadedTCPRequestHandler
)
server_thread = threading.Thread(target=cmdserver.serve_forever)

View file

@ -47,7 +47,7 @@ def signal_handler(sig, frame):
"""
print("Closing Modem...")
sock.CLOSE_SIGNAL = True
deprecated_sock.CLOSE_SIGNAL = True
sys.exit(0)
@ -144,7 +144,7 @@ try:
# check if we have an int or str as device name
# we need to wait until we got all parameters from argparse first before we can load the other modules
import sock
import deprecated_sock
try:
AudioParam.audio_input_device = int(conf.get('AUDIO', 'rx', '0'))
@ -187,7 +187,7 @@ if my_ssid not in Station.ssid_list:
Station.ssid_list.append(my_ssid)
# we need to wait until we got all parameters from argparse first before we can load the other modules
import sock
import deprecated_sock
# config logging
try:

View file

@ -13,3 +13,8 @@ class EventManager:
jsondata = {"ptt": str(on)}
data_out = json.dumps(jsondata)
self.broadcast(data_out)
def send_scatter_change(self, data):
jsondata = {"scatter": str(data)}
data_out = json.dumps(jsondata)
self.broadcast(data_out)

View file

@ -9,18 +9,16 @@ Created on 05.11.23
import requests
import threading
import time
import ujson as json
import structlog
import static
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, Statistics, TCIParam, Modem
from global_instances import HamlibParam, Modem
log = structlog.get_logger("explorer")
class explorer():
def __init__(self):
def __init__(self, config, states):
self.config = config
self.states = states
self.explorer_url = "https://api.freedata.app/explorer.php"
self.publish_interval = 120
@ -36,11 +34,11 @@ class explorer():
frequency = 0 if HamlibParam.hamlib_frequency is None else HamlibParam.hamlib_frequency
band = "USB"
callsign = str(Station.mycallsign, "utf-8")
gridsquare = str(Station.mygrid, "utf-8")
callsign = str(self.config['STATION']['mycall'], "utf-8")
gridsquare = str(self.config['STATION']['mygrid'], "utf-8")
version = str(Modem.version)
bandwidth = str(Modem.low_bandwidth_mode)
beacon = str(Beacon.beacon_state)
bandwidth = str(self.config['Modem']['low_bandwidth_mode'])
beacon = str(self.states.is_beacon_running)
strength = str(HamlibParam.hamlib_strength)
log.info("[EXPLORER] publish", frequency=frequency, band=band, callsign=callsign, gridsquare=gridsquare, version=version, bandwidth=bandwidth)

View file

@ -7,12 +7,10 @@ Created on Fri Dec 25 21:25:14 2020
import time
from datetime import datetime,timezone
import crcengine
import static
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, Statistics, TCIParam, Modem, MeshParam
from global_instances import Station, Modem
import structlog
import numpy as np
import threading
import mesh
import hashlib
import hmac
import os

View file

@ -37,7 +37,7 @@ SNR: negative --> * 2
# pylint: disable=import-outside-toplevel, attribute-defined-outside-init
from static import FRAME_TYPE
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, MeshParam, Station, Statistics, TCIParam, Modem
from global_instances import ARQ,ModemParam, MeshParam, Station, Modem
from codec2 import FREEDV_MODE
import numpy as np

View file

@ -19,9 +19,8 @@ from collections import deque
import codec2
import itertools
import numpy as np
import sock
import sounddevice as sd
from global_instances import AudioParam, HamlibParam, ModemParam, TCIParam, Modem
from global_instances import AudioParam, HamlibParam, ModemParam, Modem
from static import FRAME_TYPE
import structlog
import tci
@ -83,6 +82,11 @@ class RF:
self.tuning_range_fmin = config['Modem']['tuning_range_fmin']
self.tuning_range_fmax = config['Modem']['tuning_range_fmax']
self.tci_ip = config['TCI']['tci_ip']
self.tci_port = config['TCI']['tci_port']
self.channel_busy_delay = 0
@ -117,9 +121,7 @@ class RF:
# Init FIFO queue to store modulation out in
self.modoutqueue = deque()
self.event_manager = event_manager.EventManager([
event_queue,
sock.SOCKET_QUEUE])
self.event_manager = event_manager.EventManager([event_queue])
self.fft_queue = fft_queue
@ -222,7 +224,7 @@ class RF:
def init_tci(self):
# placeholder area for processing audio via TCI
# https://github.com/maksimus1210/TCI
self.log.warning("[MDM] [TCI] Not yet fully implemented", ip=TCIParam.ip, port=TCIParam.port)
self.log.warning("[MDM] [TCI] Not yet fully implemented", ip=self.tci_ip, port=self.tci_port)
# we are trying this by simulating an audio stream Object like with mkfifo
class Object:
@ -374,54 +376,57 @@ class RF:
"""
# self.log.debug("[MDM] callback")
x = np.frombuffer(data_in48k, dtype=np.int16)
x = self.resampler.resample48_to_8(x)
x = set_audio_volume(x, self.rx_audio_level)
try:
x = np.frombuffer(data_in48k, dtype=np.int16)
x = self.resampler.resample48_to_8(x)
x = set_audio_volume(x, self.rx_audio_level)
# audio recording for debugging purposes
if AudioParam.audio_record:
AudioParam.audio_record_file.writeframes(x)
# audio recording for debugging purposes
if AudioParam.audio_record:
AudioParam.audio_record_file.writeframes(x)
# Avoid decoding when transmitting to reduce CPU
# TODO Overriding this for testing purposes
# if not Modem.transmitting:
length_x = len(x)
# Avoid buffer overflow by filling only if buffer for
# selected datachannel mode is not full
for audiobuffer, receive, index in [
(self.sig0_datac13_buffer, RECEIVE_SIG0, 0),
(self.sig1_datac13_buffer, RECEIVE_SIG1, 1),
(self.dat0_datac1_buffer, RECEIVE_DATAC1, 2),
(self.dat0_datac3_buffer, RECEIVE_DATAC3, 3),
(self.dat0_datac4_buffer, RECEIVE_DATAC4, 4),
(self.fsk_ldpc_buffer_0, Modem.enable_fsk, 5),
(self.fsk_ldpc_buffer_1, Modem.enable_fsk, 6),
]:
if (audiobuffer.nbuffer + length_x) > audiobuffer.size:
AudioParam.buffer_overflow_counter[index] += 1
elif receive:
audiobuffer.push(x)
# end of "not Modem.transmitting" if block
# Avoid decoding when transmitting to reduce CPU
# TODO Overriding this for testing purposes
# if not Modem.transmitting:
length_x = len(x)
# Avoid buffer overflow by filling only if buffer for
# selected datachannel mode is not full
for audiobuffer, receive, index in [
(self.sig0_datac13_buffer, RECEIVE_SIG0, 0),
(self.sig1_datac13_buffer, RECEIVE_SIG1, 1),
(self.dat0_datac1_buffer, RECEIVE_DATAC1, 2),
(self.dat0_datac3_buffer, RECEIVE_DATAC3, 3),
(self.dat0_datac4_buffer, RECEIVE_DATAC4, 4),
(self.fsk_ldpc_buffer_0, Modem.enable_fsk, 5),
(self.fsk_ldpc_buffer_1, Modem.enable_fsk, 6),
]:
if (audiobuffer.nbuffer + length_x) > audiobuffer.size:
AudioParam.buffer_overflow_counter[index] += 1
elif receive:
audiobuffer.push(x)
# end of "not Modem.transmitting" if block
if not self.modoutqueue or self.mod_out_locked:
data_out48k = np.zeros(frames, dtype=np.int16)
if self.enable_fft:
self.calculate_fft(x)
else:
if not HamlibParam.ptt_state:
# TODO Moved to this place for testing
# Maybe we can avoid moments of silence before transmitting
HamlibParam.ptt_state = self.radio.set_ptt(True)
self.event_manager.send_ptt_change(True)
if not self.modoutqueue or self.mod_out_locked:
data_out48k = np.zeros(frames, dtype=np.int16)
if self.enable_fft:
self.calculate_fft(x)
else:
if not HamlibParam.ptt_state:
# TODO Moved to this place for testing
# Maybe we can avoid moments of silence before transmitting
HamlibParam.ptt_state = self.radio.set_ptt(True)
self.event_manager.send_ptt_change(True)
data_out48k = self.modoutqueue.popleft()
if self.enable_fft:
self.calculate_fft(data_out48k)
data_out48k = self.modoutqueue.popleft()
if self.enable_fft:
self.calculate_fft(data_out48k)
except Exception as e:
self.log.warning(f"[MDM] audio callback not ready yet: {e}")
try:
outdata[:] = data_out48k[:frames]
except IndexError as err:
self.log.debug(f"[MDM] callback: IndexError: {err}")
self.log.debug(f"[MDM] callback writing error: IndexError: {err}")
# return (data_out48k, audio.pyaudio.paContinue)
@ -993,8 +998,8 @@ class RF:
# set tuning range
codec2.api.freedv_set_tuning_range(
c2instance,
ctypes.c_float(ModemParam.tuning_range_fmin),
ctypes.c_float(ModemParam.tuning_range_fmax),
ctypes.c_float(self.tuning_range_fmin),
ctypes.c_float(self.tuning_range_fmax),
)
# get bytes per frame
@ -1176,7 +1181,6 @@ class RF:
def get_scatter(self, freedv: ctypes.c_void_p) -> None:
"""
Ask codec2 for data about the received signal and calculate the scatter plot.
Side effect: sets ModemParam.scatter
:param freedv: codec2 instance to query
:type freedv: ctypes.c_void_p
@ -1209,10 +1213,11 @@ class RF:
# Send all the data if we have too-few samples, otherwise send a sampling
if 150 > len(scatterdata) > 0:
ModemParam.scatter = scatterdata
self.event_manager.send_scatter_change(scatterdata)
else:
# only take every tenth data point
ModemParam.scatter = scatterdata[::10]
self.event_manager.send_scatter_change(scatterdata[::10])
def calculate_snr(self, freedv: ctypes.c_void_p) -> float:
"""

View file

@ -2,8 +2,7 @@
Hold queues used by more than one module to eliminate cyclic imports.
"""
import queue
import static
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, TCIParam, Modem
from global_instances import ARQ
DATA_QUEUE_TRANSMIT = queue.Queue()
DATA_QUEUE_RECEIVED = queue.Queue()

View file

@ -10,7 +10,7 @@ import time
import structlog
import threading
import static
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, TCIParam
from global_instances import HamlibParam
class radio:

View file

@ -9,6 +9,8 @@ import queue
import server_commands
import service_manager
import state_manager
import explorer
app = Flask(__name__)
CORS(app)
@ -41,16 +43,12 @@ app.modem_service = queue.Queue() # start / stop modem service
# init state manager
app.states = state_manager.STATES(app.state_queue)
print(app.states.testvalue)
app.states.set("testvalue", "holla")
# start service manager
service_manager.SM(app)
# start modem service
app.modem_service.put("start")
# returns a standard API response
def api_response(data):
return make_response(jsonify(data), 200)

View file

@ -4,6 +4,7 @@ import modem
import structlog
import audio
import ujson as json
import explorer
class SM:
@ -24,6 +25,11 @@ class SM:
)
runner_thread.start()
# optionally start explorer module
if self.config['STATION']['enable_explorer']:
explorer.explorer(self.config, self.states)
def runner(self):
while True:
cmd = self.modem_service.get()
@ -52,7 +58,7 @@ class SM:
if False not in audio_test and None not in audio_test and not self.states.is_modem_running:
self.log.info("starting modem....")
self.modem = modem.RF(self.config, self.modem_events, self.modem_fft, self.modem_service, self.states)
self.data_handler = data_handler.DATA(self.config, self.modem_events)
self.data_handler = data_handler.DATA(self.config, self.modem_events, self.states)
self.states.set("is_modem_running", True)
return True
elif self.states.is_modem_running:

View file

@ -11,6 +11,8 @@ class STATES:
self.is_codec2_traffic = False
self.is_modem_running = False
self.is_beacon_running = False
def set(self, key, value):
setattr(self, key, value)
self.statequeue.put(self.getAsJSON())
@ -21,4 +23,6 @@ class STATES:
"channel_busy": self.channel_busy,
"is_codec2_traffic": self.is_codec2_traffic,
"is_modem_running": self.is_modem_running,
"is_beacon_running": self.is_beacon_running,
})

View file

@ -8,7 +8,6 @@ Here we are saving application wide variables and stats, which have to be access
"""
from dataclasses import dataclass, field
from typing import List
import subprocess
from enum import Enum
import threading

View file

@ -8,11 +8,9 @@ Created on 05.11.23
# pylint: disable=import-outside-toplevel, attribute-defined-outside-init
import requests
import threading
import time
import ujson as json
import structlog
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, TCIParam, Modem
from global_instances import ARQ, HamlibParam, Station, Modem
log = structlog.get_logger("stats")

View file

@ -4,10 +4,8 @@
import structlog
import threading
import websocket
import numpy as np
import time
from queues import AUDIO_TRANSMIT_QUEUE, AUDIO_RECEIVED_QUEUE
from global_instances import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, TCIParam, Modem
class TCICtrl:
def __init__(self, hostname='127.0.0.1', port=50001):

View file

@ -1,3 +1,3 @@
#autopep8 --in-place --select W291,W293,W391,E231 --ignore E501 ../modem.py ../data_handler.py ../main.py ../sock.py ../static.py ../helpers.py
#autopep8 --in-place --select W291,W293,W391,E231 --ignore E501 ../modem.py ../data_handler.py ../deprecated_main.py ../deprecated_sock.py ../static.py ../helpers.py
autopep8 --in-place --ignore E501 ../modem.py ../data_handler.py ../main.py ../sock.py ../static.py ../helpers.py