attempt using waerfall with websockets

This commit is contained in:
DJ2LS 2023-11-09 17:14:22 +01:00
parent 165fb9588b
commit 3616e131f7
4 changed files with 132 additions and 131 deletions

View file

@ -1,25 +1,21 @@
import {
eventDispatcher
} from "../js/eventHandler.js";
import { addDataToWaterfall } from "../js/waterfallHandler.js";
let socket;
let retries = 0;
let maxRetries = 15;
function connect() {
socket = new WebSocket("ws://localhost:5000/events");
function connect(endpoint, dispatcher) {
let socket = new WebSocket("ws://localhost:5000/" + endpoint);
// handle opening
socket.addEventListener("open", function (event) {
console.log("Connected to the WebSocket server");
console.log("Connected to the WebSocket server: " + endpoint);
retries = 0; // Reset the retries back to 0 since the connection was successful
});
// handle data
socket.addEventListener("message", function (event) {
console.log("Message from server:", event.data);
eventDispatcher(event.data)
dispatcher(event.data)
});
// handle errors
@ -35,11 +31,12 @@ function connect() {
if (!event.wasClean) {
setTimeout(() => {
console.log("Reconnecting to websocket");
connect();
connect(endpoint, dispatcher);
}, 1000);
}
});
}
// Initial connection attempt
connect();
// Initial connection attempts to endpoints
connect('events', eventDispatcher);
connect('fft', addDataToWaterfall);

View file

@ -18,7 +18,7 @@ export function initWaterfall() {
}
export function addDataToWaterfall(data) {
//console.log(spectrum)
data = JSON.parse(data)
try {
spectrum.addData(data);
} catch (e) {

View file

@ -12,6 +12,7 @@ Created on Wed Dec 23 07:04:24 2020
import atexit
import ctypes
import os
import queue
import sys
import threading
import time
@ -63,7 +64,7 @@ class RF:
log = structlog.get_logger("RF")
def __init__(self, config, event_queue) -> None:
def __init__(self, config, event_queue, fft_queue) -> None:
self.config = config
self.sampler_avg = 0
@ -109,13 +110,12 @@ class RF:
# Init FIFO queue to store modulation out in
self.modoutqueue = deque()
# Define fft_data buffer
self.fft_data = bytes()
self.event_manager = event_manager.EventManager([
event_queue,
sock.SOCKET_QUEUE])
self.fft_queue = fft_queue
self.init_codec2()
self.init_audio()
self.init_rig_control()
@ -247,8 +247,8 @@ class RF:
x = self.audio_received_queue.get()
x = np.frombuffer(x, dtype=np.int16)
# x = self.resampler.resample48_to_8(x)
self.fft_data = x
if AudioParam.enable_fft:
self.calculate_fft(x)
length_x = len(x)
for data_buffer, receive in [
@ -361,7 +361,8 @@ class RF:
if not self.modoutqueue or self.mod_out_locked:
data_out48k = np.zeros(frames, dtype=np.int16)
self.fft_data = x
if AudioParam.enable_fft:
self.calculate_fft(x)
else:
if not HamlibParam.ptt_state:
# TODO Moved to this place for testing
@ -370,7 +371,8 @@ class RF:
self.event_manager.send_ptt_change(True)
data_out48k = self.modoutqueue.popleft()
self.fft_data = data_out48k
if AudioParam.enable_fft:
self.calculate_fft(data_out48k)
try:
outdata[:] = data_out48k[:frames]
@ -678,11 +680,6 @@ class RF:
self.modoutqueue.append(c)
def init_decoders(self):
if AudioParam.enable_fft:
fft_thread = threading.Thread(
target=self.calculate_fft, name="FFT_THREAD", daemon=True
)
fft_thread.start()
if Modem.enable_fsk:
audio_thread_fsk_ldpc0 = threading.Thread(
@ -1280,7 +1277,7 @@ class RF:
)
threading.Event().wait(1)
def calculate_fft(self) -> None:
def calculate_fft(self, data) -> None:
"""
Calculate an average signal strength of the channel to assess
whether the channel is "busy."
@ -1291,18 +1288,11 @@ class RF:
# Initialize dbfs counter
rms_counter = 0
while True:
# threading.Event().wait(0.01)
threading.Event().wait(0.01)
# WE NEED TO OPTIMIZE THIS!
# Start calculating the FFT once enough samples are captured.
if len(self.fft_data) >= 128:
# https://gist.github.com/ZWMiller/53232427efc5088007cab6feee7c6e4c
# Fast Fourier Transform, 10*log10(abs) is to scale it to dB
# and make sure it's not imaginary
try:
fftarray = np.fft.rfft(self.fft_data)
fftarray = np.fft.rfft(data)
# Set value 0 to 1 to avoid division by zero
fftarray[fftarray == 0] = 1
@ -1325,7 +1315,7 @@ class RF:
# calculate dbfs every 50 cycles for reducing CPU load
rms_counter += 1
if rms_counter > 50:
d = np.frombuffer(self.fft_data, np.int16).astype(np.float32)
d = np.frombuffer(data, np.int16).astype(np.float32)
# calculate RMS and then dBFS
# https://dsp.stackexchange.com/questions/8785/how-to-compute-dbfs
# try except for avoiding runtime errors by division/0
@ -1399,12 +1389,17 @@ class RF:
# When our channel busy counter reaches 0, toggle state to False
if ModemParam.channel_busy_delay == 0:
ModemParam.channel_busy = False
AudioParam.fft = dfftlist[:315] # 315 --> bandwidth 3200
# erase queue if greater than 10
if self.fft_queue.qsize() >= 10:
self.fft_queue = queue.Queue()
self.fft_queue.put(dfftlist[:315]) # 315 --> bandwidth 3200
except Exception as err:
self.log.error(f"[MDM] calculate_fft: Exception: {err}")
self.log.debug("[MDM] Setting fft=0")
# else 0
AudioParam.fft = [0]
self.fft_queue.put([0])
def set_frames_per_burst(self, frames_per_burst: int) -> None:
"""

View file

@ -38,7 +38,9 @@ set_config()
# start modem
app.modem_events = queue.Queue()
app.modem = modem.RF(app.config_manager.config, app.modem_events)
app.modem_fft = queue.Queue()
app.modem = modem.RF(app.config_manager.config, app.modem_events, app.modem_fft)
data_handler.DATA(app.config_manager.config, app.modem_events)
## REST API
@ -127,8 +129,15 @@ def post_ping():
# Event websocket
@sock.route('/events')
def echo(sock):
def sock_events(sock):
# it seems we have to keep the logics inside a loop, otherwise connection will be terminated
while True:
ev = app.modem_events.get()
sock.send(ev)
@sock.route('/fft')
def sock_fft(sock):
# it seems we have to keep the logics inside a loop, otherwise connection will be terminated
while True:
fft = app.modem_fft.get()
sock.send(fft)