introduced state manager and changed config.ini

This commit is contained in:
DJ2LS 2023-11-11 20:01:15 +01:00
parent 9f7bdfbc2b
commit bd2e173620
5 changed files with 80 additions and 46 deletions

View file

@ -182,25 +182,27 @@ export function getModemConfigAsJSON() {
const configData = { const configData = {
AUDIO: { AUDIO: {
auto_tune: settings.auto_tune, auto_tune: settings.auto_tune,
rx: settings.rx_audio, input_device: settings.rx_audio,
rxaudiolevel: settings.rx_audio_level, rxaudiolevel: settings.rx_audio_level,
tx: settings.tx_audio, output_device: settings.tx_audio,
txaudiolevel: settings.tx_audio_level, txaudiolevel: settings.tx_audio_level,
//enable_auto_tune: settings.tx_audio_level,
}, },
MESH: { MESH: {
enable_protocol: settings.enable_mesh_features, enable_protocol: settings.enable_mesh_features,
}, },
Modem: { Modem: {
explorer: settings.enable_explorer, enable_explorer: settings.enable_explorer,
fft: settings.enable_fft, enable_fft: settings.enable_fft,
fmax: settings.tuning_range_fmax, tuning_range_fmax: settings.tuning_range_fmax,
fmin: settings.tuning_range_fmin, tuning_range_fmin: settings.tuning_range_fmin,
fsk: settings.enable_fsk, enable_fsk: settings.enable_fsk,
narrowband: settings.low_bandwidth_mode, enable_low_bandwidth_mode: settings.enable_low_bandwidth_mode,
qrv: settings.respond_to_cq, respond_to_cq: settings.respond_to_cq,
rx_buffer_size: settings.rx_buffer_size, rx_buffer_size: settings.rx_buffer_size,
scatter: "False", enable_scatter: "False",
stats: settings.explorer_stats, enable_stats: settings.explorer_stats,
tx_delay: settings.tx_delay, tx_delay: settings.tx_delay,
}, },
NETWORK: { NETWORK: {

View file

@ -62,23 +62,28 @@ class RF:
log = structlog.get_logger("RF") log = structlog.get_logger("RF")
def __init__(self, config, event_queue, fft_queue, service_queue) -> None: def __init__(self, config, event_queue, fft_queue, service_queue, states) -> None:
self.config = config self.config = config
self.service_queue = service_queue self.service_queue = service_queue
self.states = states
self.sampler_avg = 0 self.sampler_avg = 0
self.buffer_avg = 0 self.buffer_avg = 0
# these are crc ids now # these are crc ids now
self.audio_input_device = config['AUDIO']['rx'] self.audio_input_device = config['AUDIO']['input_device']
self.audio_output_device = config['AUDIO']['tx'] self.audio_output_device = config['AUDIO']['output_device']
self.rx_audio_level = config['AUDIO']['rxaudiolevel'] self.rx_audio_level = config['AUDIO']['rxaudiolevel']
self.tx_audio_level = config['AUDIO']['txaudiolevel'] self.tx_audio_level = config['AUDIO']['txaudiolevel']
self.enable_audio_auto_tune = config['AUDIO']['auto_tune'] self.enable_audio_auto_tune = config['AUDIO']['enable_auto_tune']
self.enable_fft = config['Modem']['fft'] self.enable_fft = config['Modem']['enable_fft']
self.tx_delay = config['Modem']['tx_delay']
self.tuning_range_fmin = config['Modem']['tuning_range_fmin']
self.tuning_range_fmax = config['Modem']['tuning_range_fmax']
self.channel_busy_delay = 0
self.AUDIO_SAMPLE_RATE_RX = 48000 self.AUDIO_SAMPLE_RATE_RX = 48000
@ -454,7 +459,7 @@ class RF:
Modem.transmitting = True Modem.transmitting = True
# if we're transmitting FreeDATA signals, reset channel busy state # if we're transmitting FreeDATA signals, reset channel busy state
ModemParam.channel_busy = False self.states.channel_busy = False
start_of_transmission = time.time() start_of_transmission = time.time()
# TODO Moved ptt toggle some steps before audio is ready for testing # TODO Moved ptt toggle some steps before audio is ready for testing
@ -490,15 +495,15 @@ class RF:
) )
# Add empty data to handle ptt toggle time # Add empty data to handle ptt toggle time
if ModemParam.tx_delay > 0: if self.tx_delay > 0:
data_delay = int(self.MODEM_SAMPLE_RATE * (ModemParam.tx_delay / 1000)) # type: ignore data_delay = int(self.MODEM_SAMPLE_RATE * (self.tx_delay / 1000)) # type: ignore
mod_out_silence = ctypes.create_string_buffer(data_delay * 2) mod_out_silence = ctypes.create_string_buffer(data_delay * 2)
txbuffer = bytes(mod_out_silence) txbuffer = bytes(mod_out_silence)
else: else:
txbuffer = bytes() txbuffer = bytes()
self.log.debug( self.log.debug(
"[MDM] TRANSMIT", mode=self.MODE, payload=payload_bytes_per_frame, delay=ModemParam.tx_delay "[MDM] TRANSMIT", mode=self.MODE, payload=payload_bytes_per_frame, delay=self.tx_delay
) )
for _ in range(repeats): for _ in range(repeats):
@ -600,7 +605,7 @@ class RF:
tci_timeout_reached = True tci_timeout_reached = True
threading.Event().wait(0.01) threading.Event().wait(0.01)
# if we're transmitting FreeDATA signals, reset channel busy state # if we're transmitting FreeDATA signals, reset channel busy state
ModemParam.channel_busy = False self.states.channel_busy = False
HamlibParam.ptt_state = self.radio.set_ptt(False) HamlibParam.ptt_state = self.radio.set_ptt(False)
@ -649,7 +654,7 @@ class RF:
def transmit_morse(self, repeats, repeat_delay, frames): def transmit_morse(self, repeats, repeat_delay, frames):
Modem.transmitting = True Modem.transmitting = True
# if we're transmitting FreeDATA signals, reset channel busy state # if we're transmitting FreeDATA signals, reset channel busy state
ModemParam.channel_busy = False self.states.channel_busy = False
self.log.debug( self.log.debug(
"[MDM] TRANSMIT", mode="MORSE" "[MDM] TRANSMIT", mode="MORSE"
) )
@ -683,7 +688,7 @@ class RF:
threading.Event().wait(0.01) threading.Event().wait(0.01)
# if we're transmitting FreeDATA signals, reset channel busy state # if we're transmitting FreeDATA signals, reset channel busy state
ModemParam.channel_busy = False self.states.channel_busy = False
HamlibParam.ptt_state = self.radio.set_ptt(False) HamlibParam.ptt_state = self.radio.set_ptt(False)
@ -809,25 +814,25 @@ class RF:
if rx_status not in [0]: if rx_status not in [0]:
# we need to disable this if in testmode as its causing problems with FIFO it seems # we need to disable this if in testmode as its causing problems with FIFO it seems
if not TESTMODE: if not TESTMODE:
ModemParam.is_codec2_traffic = True self.states.is_codec2_traffic = True
self.is_codec2_traffic_counter = self.is_codec2_traffic_cooldown self.is_codec2_traffic_counter = self.is_codec2_traffic_cooldown
if not ModemParam.channel_busy: if not self.states.channel_busy:
self.log.debug("[MDM] Setting channel_busy since codec2 data detected") self.log.debug("[MDM] Setting channel_busy since codec2 data detected")
ModemParam.channel_busy=True self.states.channel_busy=True
ModemParam.channel_busy_delay += 10 self.channel_busy_delay += 10
self.log.debug( self.log.debug(
"[MDM] [demod_audio] modem state", mode=mode_name, rx_status=rx_status, "[MDM] [demod_audio] modem state", mode=mode_name, rx_status=rx_status,
sync_flag=codec2.api.rx_sync_flags_to_text[rx_status] sync_flag=codec2.api.rx_sync_flags_to_text[rx_status]
) )
else: else:
ModemParam.is_codec2_traffic = False self.states.is_codec2_traffic = False
# decrement codec traffic counter for making state smoother # decrement codec traffic counter for making state smoother
if self.is_codec2_traffic_counter > 0: if self.is_codec2_traffic_counter > 0:
self.is_codec2_traffic_counter -= 1 self.is_codec2_traffic_counter -= 1
ModemParam.is_codec2_traffic = True self.states.is_codec2_traffic = True
else: else:
ModemParam.is_codec2_traffic = False self.states.is_codec2_traffic = False
if rx_status == 10: if rx_status == 10:
state_buffer.append(rx_status) state_buffer.append(rx_status)
@ -1321,9 +1326,6 @@ class RF:
Calculate an average signal strength of the channel to assess Calculate an average signal strength of the channel to assess
whether the channel is "busy." whether the channel is "busy."
""" """
# Initialize channel_busy_delay counter
#channel_busy_delay = 0
# Initialize dbfs counter # Initialize dbfs counter
rms_counter = 0 rms_counter = 0
@ -1412,22 +1414,22 @@ class RF:
# so we have a smoother state toggle # so we have a smoother state toggle
if np.sum(slotdfft[slotdfft > avg + 15]) >= 200 and not Modem.transmitting: if np.sum(slotdfft[slotdfft > avg + 15]) >= 200 and not Modem.transmitting:
addDelay=True addDelay=True
ModemParam.channel_busy_slot[slot] = True self.states.channel_busy_slot[slot] = True
else: else:
ModemParam.channel_busy_slot[slot] = False self.states.channel_busy_slot[slot] = False
# increment slot # increment slot
slot += 1 slot += 1
if addDelay: if addDelay:
# Limit delay counter to a maximum of 200. The higher this value, # Limit delay counter to a maximum of 200. The higher this value,
# the longer we will wait until releasing state # the longer we will wait until releasing state
ModemParam.channel_busy = True self.states.channel_busy = True
ModemParam.channel_busy_delay = min(ModemParam.channel_busy_delay + 10, 200) self.channel_busy_delay = min(self.channel_busy_delay + 10, 200)
else: else:
# Decrement channel busy counter if no signal has been detected. # Decrement channel busy counter if no signal has been detected.
ModemParam.channel_busy_delay = max(ModemParam.channel_busy_delay - 1, 0) self.channel_busy_delay = max(self.channel_busy_delay - 1, 0)
# When our channel busy counter reaches 0, toggle state to False # When our channel busy counter reaches 0, toggle state to False
if ModemParam.channel_busy_delay == 0: if self.channel_busy_delay == 0:
ModemParam.channel_busy = False self.states.channel_busy = False
# erase queue if greater than 10 # erase queue if greater than 10
if self.fft_queue.qsize() >= 10: if self.fft_queue.qsize() >= 10:

View file

@ -8,6 +8,7 @@ import audio
import queue import queue
import server_commands import server_commands
import service_manager import service_manager
import state_manager
app = Flask(__name__) app = Flask(__name__)
CORS(app) CORS(app)
@ -32,10 +33,17 @@ def set_config():
set_config() set_config()
# start modem # start modem
app.state_queue = queue.Queue() # queue which holds latest events
app.modem_events = queue.Queue() # queue which holds latest events app.modem_events = queue.Queue() # queue which holds latest events
app.modem_fft = queue.Queue() # queue which holds lates fft data app.modem_fft = queue.Queue() # queue which holds lates fft data
app.modem_service = queue.Queue() # start / stop modem service 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 # start service manager
service_manager.SM(app) service_manager.SM(app)
@ -120,7 +128,7 @@ def post_send_fec_frame():
return api_response(request.json) return api_response(request.json)
@app.route('/modem/fec_is_writing', methods=['POST']) @app.route('/modem/fec_is_writing', methods=['POST'])
def post_send_fec_frame(): def post_send_fec_is_writing():
if request.method not in ['POST']: if request.method not in ['POST']:
return api_response({"info": "endpoint for triggering a IS WRITING frame via POST"}) return api_response({"info": "endpoint for triggering a IS WRITING frame via POST"})
server_commands.modem_fec_is_writing(request.json) server_commands.modem_fec_is_writing(request.json)

View file

@ -15,7 +15,7 @@ class SM:
self.modem_events = app.modem_events self.modem_events = app.modem_events
self.modem_fft = app.modem_fft self.modem_fft = app.modem_fft
self.modem_service = app.modem_service self.modem_service = app.modem_service
self.states = app.states
runner_thread = threading.Thread( runner_thread = threading.Thread(
target=self.runner, name="runner thread", daemon=True target=self.runner, name="runner thread", daemon=True
@ -26,11 +26,11 @@ class SM:
while True: while True:
cmd = self.modem_service.get() cmd = self.modem_service.get()
if cmd in ['start'] and not self.modem: if cmd in ['start'] and not self.modem:
audio_test = audio.test_audio_devices(self.config['AUDIO']['rx'], self.config['AUDIO']['tx']) audio_test = audio.test_audio_devices(self.config['AUDIO']['input_device'], self.config['AUDIO']['output_device'])
print(audio_test) print(audio_test)
if False not in audio_test and None not in audio_test: if False not in audio_test and None not in audio_test:
self.log.info("starting modem....") self.log.info("starting modem....")
self.modem = modem.RF(self.config, self.modem_events, self.modem_fft, self.modem_service) 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)
else: else:
self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1]) self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1])

22
modem/state_manager.py Normal file
View file

@ -0,0 +1,22 @@
class STATES:
def __init__(self, statequeue):
self.statequeue = statequeue
self.testvalue = "Hello World!"
self.channel_busy = False
self.channel_busy_slot = [False, False, False, False, False]
self.is_codec2_traffic = False
def set(self, key, value):
setattr(self, key, value)
self.statequeue.put(self.getAsJSON())
def getAsJSON(self):
return {
"freedata-message": "state-change",
"channel_busy": self.channel_busy,
"is_codec2_traffic": self.is_codec2_traffic
}