mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
config fixes and adjustments
This commit is contained in:
parent
131ec6fa63
commit
d74dda0bc5
143
modem/config.py
143
modem/config.py
|
@ -17,13 +17,12 @@ class CONFIG:
|
|||
|
||||
try:
|
||||
self.config_name = configfile
|
||||
|
||||
except Exception:
|
||||
self.config_name = "config.ini"
|
||||
|
||||
self.log.info("[CFG] logfile init", file=self.config_name)
|
||||
self.log.info("[CFG] config init", file=self.config_name)
|
||||
|
||||
# check if log file exists
|
||||
# check if config file exists
|
||||
self.config_exists()
|
||||
|
||||
def config_exists(self):
|
||||
|
@ -36,30 +35,110 @@ class CONFIG:
|
|||
self.log.error("[CFG] logfile init error", e=configerror)
|
||||
return False
|
||||
|
||||
def write_config(self, section: str, key: str, value):
|
||||
"""
|
||||
write values to config
|
||||
"""
|
||||
|
||||
# Validates config data
|
||||
def validate_network_settings(self, data):
|
||||
if 'modemport' in data:
|
||||
if not isinstance(data['modemport'], int):
|
||||
raise ValueError("'modemport' in 'NETWORK' must be an integer.")
|
||||
|
||||
def validate_station_settings(self, data):
|
||||
for setting in ['mycall', 'mygrid']:
|
||||
if setting in data and not data[setting]:
|
||||
raise ValueError(f"'{setting}' in 'STATION' cannot be empty.")
|
||||
if 'ssid_list' in data and not isinstance(data['ssid_list'], list):
|
||||
raise ValueError("'ssid_list' in 'STATION' needs to be a list.")
|
||||
|
||||
def validate_audio_settings(self, data):
|
||||
for setting in ['input_device', 'output_device']:
|
||||
if setting in data and not isinstance(data[setting], str):
|
||||
raise ValueError(f"'{setting}' in 'AUDIO' must be a string.")
|
||||
for setting in ['rx_audio_level', 'tx_audio_level']:
|
||||
if setting in data and not isinstance(data[setting], int):
|
||||
raise ValueError(f"'{setting}' in 'AUDIO' must be an integer.")
|
||||
|
||||
def validate_radio_settings(self, data):
|
||||
if 'radioport' in data and not (data['radioport'] is None or isinstance(data['radioport'], int)):
|
||||
raise ValueError("'radioport' in 'RADIO' must be None or an integer.")
|
||||
|
||||
def validate_tci_settings(self, data):
|
||||
if 'tci_ip' in data and not isinstance(data['tci_ip'], str):
|
||||
raise ValueError("'tci_ip' in 'TCI' must be a string.")
|
||||
if 'tci_port' in data and not isinstance(data['tci_port'], int):
|
||||
raise ValueError("'tci_port' in 'TCI' must be an integer.")
|
||||
|
||||
def validate_modem_settings(self, data):
|
||||
for setting in ['enable_fft', 'enable_fsk', 'enable_low_bandwidth_mode', 'respond_to_cq', 'enable_scatter']:
|
||||
if setting in data and not isinstance(data[setting], bool):
|
||||
raise ValueError(f"'{setting}' in 'MODEM' must be a boolean.")
|
||||
for setting in ['tuning_range_fmax', 'tuning_range_fmin', 'rx_buffer_size', 'tx_delay']:
|
||||
if setting in data and not isinstance(data[setting], int):
|
||||
raise ValueError(f"'{setting}' in 'MODEM' must be an integer.")
|
||||
|
||||
def validate_mesh_settings(self, data):
|
||||
if 'enable_protocol' in data and not isinstance(data['enable_protocol'], bool):
|
||||
raise ValueError("'enable_protocol' in 'MESH' must be a boolean.")
|
||||
|
||||
def validate(self, data):
|
||||
for section in data:
|
||||
for setting in data[section]:
|
||||
for section, settings in data.items():
|
||||
if section == 'NETWORK':
|
||||
if setting == 'modemport' and int(data[section][setting]) == 0:
|
||||
raise Exception("'modemport' should be an integer")
|
||||
if section == 'STATION':
|
||||
if setting == 'mycall' and len(data[section][setting]) <= 0:
|
||||
raise Exception("'%s' can't be empty" % setting)
|
||||
if setting == 'mygrid' and len(data[section][setting]) <= 0:
|
||||
raise Exception("'%s' can't be empty" % setting)
|
||||
if setting == 'ssid_list' and not isinstance(data[section][setting], list):
|
||||
raise Exception("'%s' needs to be a list" % setting)
|
||||
# TODO finish this for all config settings!
|
||||
self.validate_network_settings(settings)
|
||||
elif section == 'STATION':
|
||||
self.validate_station_settings(settings)
|
||||
elif section == 'AUDIO':
|
||||
self.validate_audio_settings(settings)
|
||||
elif section == 'RADIO':
|
||||
self.validate_radio_settings(settings)
|
||||
elif section == 'TCI':
|
||||
self.validate_tci_settings(settings)
|
||||
elif section == 'MESH':
|
||||
self.validate_mesh_settings(settings)
|
||||
elif section == 'MODEM':
|
||||
self.validate_modem_settings(settings)
|
||||
else:
|
||||
self.log.warning("wrong config", section=section)
|
||||
|
||||
# converts values of settings from String to Value.
|
||||
# For example 'False' (type String) will be converted to False (type Bool)
|
||||
def convert_types(self, config):
|
||||
for setting in config:
|
||||
value = config[setting]
|
||||
|
||||
if isinstance(value, dict):
|
||||
# If the value is a dictionary, apply the function recursively
|
||||
config[setting] = self.convert_types(value)
|
||||
|
||||
elif isinstance(value, list):
|
||||
# If the value is a list, iterate through the list
|
||||
new_list = []
|
||||
for item in value:
|
||||
# Apply the function to each dictionary item in the list
|
||||
if isinstance(item, dict):
|
||||
new_list.append(self.convert_types(item))
|
||||
else:
|
||||
new_list.append(item)
|
||||
config[setting] = new_list
|
||||
|
||||
elif isinstance(value, str):
|
||||
# Attempt to convert string values
|
||||
if value.lstrip('-').isdigit():
|
||||
config[setting] = int(value)
|
||||
else:
|
||||
try:
|
||||
# Try converting to a float
|
||||
float_value = float(value)
|
||||
# If it's actually an integer (like -50.0), convert it to an integer
|
||||
config[setting] = int(float_value) if float_value.is_integer() else float_value
|
||||
except ValueError:
|
||||
# Convert to boolean if applicable
|
||||
if value.lower() in ['true', 'false']:
|
||||
config[setting] = value.lower() == 'true'
|
||||
|
||||
return config
|
||||
|
||||
# Handle special setting data type conversion
|
||||
# is_writing means data from a dict being writen to the config file
|
||||
# if False, it means the opposite direction
|
||||
# TODO check if we can include this in function "convert_types"
|
||||
def handle_setting(self, section, setting, value, is_writing = False):
|
||||
if (section == 'STATION' and setting == 'ssid_list'):
|
||||
if (is_writing):
|
||||
|
@ -71,7 +150,8 @@ class CONFIG:
|
|||
|
||||
# Sets and writes config data from a dict containing data settings
|
||||
def write(self, data):
|
||||
|
||||
# convert datatypes
|
||||
data = self.convert_types(data)
|
||||
# Validate config data before writing
|
||||
self.validate(data)
|
||||
|
||||
|
@ -98,11 +178,13 @@ class CONFIG:
|
|||
"""
|
||||
read config file
|
||||
"""
|
||||
self.log.info("[CFG] reading...")
|
||||
if not self.config_exists():
|
||||
return False
|
||||
|
||||
# at first just copy the config as read from file
|
||||
result = {s:dict(self.config.items(s)) for s in self.config.sections()}
|
||||
result = self.convert_types(result)
|
||||
|
||||
# handle the special settings (like 'ssid_list')
|
||||
for section in result:
|
||||
|
@ -111,22 +193,3 @@ class CONFIG:
|
|||
section, setting, result[section][setting], False)
|
||||
|
||||
return result
|
||||
|
||||
def get(self, area, key, default):
|
||||
"""
|
||||
read from config and add if not exists
|
||||
|
||||
"""
|
||||
|
||||
for _ in range(2):
|
||||
try:
|
||||
parameter = (
|
||||
self.config[area][key] in ["True", "true", True]
|
||||
if default in ["True", "true", True, "False", "false", False]
|
||||
else self.config[area][key]
|
||||
)
|
||||
except KeyError:
|
||||
self.config[area][key] = str(default)
|
||||
|
||||
self.log.info("[CFG] reading...", parameter=parameter, key=key)
|
||||
return parameter
|
||||
|
|
|
@ -285,7 +285,6 @@ class DATA:
|
|||
def worker_transmit(self) -> None:
|
||||
"""Dispatch incoming UI instructions for transmitting operations"""
|
||||
while True:
|
||||
print("ja?")
|
||||
|
||||
data = self.data_queue_transmit.get()
|
||||
print(data)
|
||||
|
@ -365,7 +364,7 @@ class DATA:
|
|||
self.log.error(
|
||||
"[Modem] worker_transmit: received invalid command:", data=data
|
||||
)
|
||||
print("jaaaa")
|
||||
|
||||
def worker_receive(self) -> None:
|
||||
"""Queue received data for processing"""
|
||||
while True:
|
||||
|
|
|
@ -63,6 +63,7 @@ class RF:
|
|||
|
||||
def __init__(self, config, event_queue, fft_queue, service_queue, states) -> None:
|
||||
self.config = config
|
||||
print(config)
|
||||
self.service_queue = service_queue
|
||||
self.states = states
|
||||
|
||||
|
@ -79,7 +80,6 @@ class RF:
|
|||
self.enable_fft = config['MODEM']['enable_fft']
|
||||
self.enable_scatter = config['MODEM']['enable_scatter']
|
||||
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']
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ set_config()
|
|||
# start modem
|
||||
app.state_queue = queue.Queue() # queue which holds latest states
|
||||
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 latest fft data
|
||||
app.modem_service = queue.Queue() # start / stop modem service
|
||||
|
||||
# init state manager
|
||||
|
@ -204,8 +204,11 @@ def sock_watchdog(sock, client_list, event_queue):
|
|||
try:
|
||||
sock.receive(timeout=1)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print(f"client connection lost: {e}")
|
||||
try:
|
||||
client_list.remove(sock)
|
||||
except Exception as err:
|
||||
print(f"error removing client from list: {e} | {err}")
|
||||
break
|
||||
return
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class SM:
|
|||
self.modem = False
|
||||
self.data_handler = False
|
||||
|
||||
self.config = app.config_manager.config
|
||||
self.config = app.config_manager.read()
|
||||
self.modem_events = app.modem_events
|
||||
self.modem_fft = app.modem_fft
|
||||
self.modem_service = app.modem_service
|
||||
|
|
|
@ -3,7 +3,7 @@ import ujson as json
|
|||
class STATES:
|
||||
def __init__(self, statequeue):
|
||||
self.statequeue = statequeue
|
||||
|
||||
self.newstate = None
|
||||
self.channel_busy = False
|
||||
self.channel_busy_slot = [False, False, False, False, False]
|
||||
self.is_codec2_traffic = False
|
||||
|
@ -16,7 +16,12 @@ class STATES:
|
|||
|
||||
def set(self, key, value):
|
||||
setattr(self, key, value)
|
||||
self.statequeue.put(self.getAsJSON())
|
||||
|
||||
# only process data if changed
|
||||
new_state = self.getAsJSON()
|
||||
if new_state != self.newstate:
|
||||
self.statequeue.put(new_state)
|
||||
self.newstate = new_state
|
||||
|
||||
def getAsJSON(self):
|
||||
return json.dumps({
|
||||
|
|
Loading…
Reference in a new issue