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
6 changed files with 123 additions and 53 deletions
151
modem/config.py
151
modem/config.py
|
@ -17,13 +17,12 @@ class CONFIG:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.config_name = configfile
|
self.config_name = configfile
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
self.config_name = "config.ini"
|
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()
|
self.config_exists()
|
||||||
|
|
||||||
def config_exists(self):
|
def config_exists(self):
|
||||||
|
@ -36,30 +35,110 @@ class CONFIG:
|
||||||
self.log.error("[CFG] logfile init error", e=configerror)
|
self.log.error("[CFG] logfile init error", e=configerror)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def write_config(self, section: str, key: str, value):
|
|
||||||
"""
|
|
||||||
write values to config
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Validates config data
|
# 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):
|
def validate(self, data):
|
||||||
for section in data:
|
for section, settings in data.items():
|
||||||
for setting in data[section]:
|
if section == 'NETWORK':
|
||||||
if section == 'NETWORK':
|
self.validate_network_settings(settings)
|
||||||
if setting == 'modemport' and int(data[section][setting]) == 0:
|
elif section == 'STATION':
|
||||||
raise Exception("'modemport' should be an integer")
|
self.validate_station_settings(settings)
|
||||||
if section == 'STATION':
|
elif section == 'AUDIO':
|
||||||
if setting == 'mycall' and len(data[section][setting]) <= 0:
|
self.validate_audio_settings(settings)
|
||||||
raise Exception("'%s' can't be empty" % setting)
|
elif section == 'RADIO':
|
||||||
if setting == 'mygrid' and len(data[section][setting]) <= 0:
|
self.validate_radio_settings(settings)
|
||||||
raise Exception("'%s' can't be empty" % setting)
|
elif section == 'TCI':
|
||||||
if setting == 'ssid_list' and not isinstance(data[section][setting], list):
|
self.validate_tci_settings(settings)
|
||||||
raise Exception("'%s' needs to be a list" % setting)
|
elif section == 'MESH':
|
||||||
# TODO finish this for all config settings!
|
self.validate_mesh_settings(settings)
|
||||||
|
elif section == 'MODEM':
|
||||||
# Handle special setting data type conversion
|
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
|
# is_writing means data from a dict being writen to the config file
|
||||||
# if False, it means the opposite direction
|
# 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):
|
def handle_setting(self, section, setting, value, is_writing = False):
|
||||||
if (section == 'STATION' and setting == 'ssid_list'):
|
if (section == 'STATION' and setting == 'ssid_list'):
|
||||||
if (is_writing):
|
if (is_writing):
|
||||||
|
@ -71,7 +150,8 @@ class CONFIG:
|
||||||
|
|
||||||
# Sets and writes config data from a dict containing data settings
|
# Sets and writes config data from a dict containing data settings
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
|
# convert datatypes
|
||||||
|
data = self.convert_types(data)
|
||||||
# Validate config data before writing
|
# Validate config data before writing
|
||||||
self.validate(data)
|
self.validate(data)
|
||||||
|
|
||||||
|
@ -98,35 +178,18 @@ class CONFIG:
|
||||||
"""
|
"""
|
||||||
read config file
|
read config file
|
||||||
"""
|
"""
|
||||||
|
self.log.info("[CFG] reading...")
|
||||||
if not self.config_exists():
|
if not self.config_exists():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# at first just copy the config as read from file
|
# at first just copy the config as read from file
|
||||||
result = {s:dict(self.config.items(s)) for s in self.config.sections()}
|
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')
|
# handle the special settings (like 'ssid_list')
|
||||||
for section in result:
|
for section in result:
|
||||||
for setting in result[section]:
|
for setting in result[section]:
|
||||||
result[section][setting] = self.handle_setting(
|
result[section][setting] = self.handle_setting(
|
||||||
section, setting, result[section][setting], False)
|
section, setting, result[section][setting], False)
|
||||||
|
|
||||||
return result
|
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:
|
def worker_transmit(self) -> None:
|
||||||
"""Dispatch incoming UI instructions for transmitting operations"""
|
"""Dispatch incoming UI instructions for transmitting operations"""
|
||||||
while True:
|
while True:
|
||||||
print("ja?")
|
|
||||||
|
|
||||||
data = self.data_queue_transmit.get()
|
data = self.data_queue_transmit.get()
|
||||||
print(data)
|
print(data)
|
||||||
|
@ -365,7 +364,7 @@ class DATA:
|
||||||
self.log.error(
|
self.log.error(
|
||||||
"[Modem] worker_transmit: received invalid command:", data=data
|
"[Modem] worker_transmit: received invalid command:", data=data
|
||||||
)
|
)
|
||||||
print("jaaaa")
|
|
||||||
def worker_receive(self) -> None:
|
def worker_receive(self) -> None:
|
||||||
"""Queue received data for processing"""
|
"""Queue received data for processing"""
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -63,6 +63,7 @@ class RF:
|
||||||
|
|
||||||
def __init__(self, config, event_queue, fft_queue, service_queue, states) -> None:
|
def __init__(self, config, event_queue, fft_queue, service_queue, states) -> None:
|
||||||
self.config = config
|
self.config = config
|
||||||
|
print(config)
|
||||||
self.service_queue = service_queue
|
self.service_queue = service_queue
|
||||||
self.states = states
|
self.states = states
|
||||||
|
|
||||||
|
@ -79,7 +80,6 @@ class RF:
|
||||||
self.enable_fft = config['MODEM']['enable_fft']
|
self.enable_fft = config['MODEM']['enable_fft']
|
||||||
self.enable_scatter = config['MODEM']['enable_scatter']
|
self.enable_scatter = config['MODEM']['enable_scatter']
|
||||||
self.tx_delay = config['MODEM']['tx_delay']
|
self.tx_delay = config['MODEM']['tx_delay']
|
||||||
|
|
||||||
self.tuning_range_fmin = config['MODEM']['tuning_range_fmin']
|
self.tuning_range_fmin = config['MODEM']['tuning_range_fmin']
|
||||||
self.tuning_range_fmax = config['MODEM']['tuning_range_fmax']
|
self.tuning_range_fmax = config['MODEM']['tuning_range_fmax']
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ set_config()
|
||||||
# start modem
|
# start modem
|
||||||
app.state_queue = queue.Queue() # queue which holds latest states
|
app.state_queue = queue.Queue() # queue which holds latest states
|
||||||
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 latest fft data
|
||||||
app.modem_service = queue.Queue() # start / stop modem service
|
app.modem_service = queue.Queue() # start / stop modem service
|
||||||
|
|
||||||
# init state manager
|
# init state manager
|
||||||
|
@ -204,8 +204,11 @@ def sock_watchdog(sock, client_list, event_queue):
|
||||||
try:
|
try:
|
||||||
sock.receive(timeout=1)
|
sock.receive(timeout=1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(f"client connection lost: {e}")
|
||||||
client_list.remove(sock)
|
try:
|
||||||
|
client_list.remove(sock)
|
||||||
|
except Exception as err:
|
||||||
|
print(f"error removing client from list: {e} | {err}")
|
||||||
break
|
break
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ class SM:
|
||||||
self.modem = False
|
self.modem = False
|
||||||
self.data_handler = 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_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
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ujson as json
|
||||||
class STATES:
|
class STATES:
|
||||||
def __init__(self, statequeue):
|
def __init__(self, statequeue):
|
||||||
self.statequeue = statequeue
|
self.statequeue = statequeue
|
||||||
|
self.newstate = None
|
||||||
self.channel_busy = False
|
self.channel_busy = False
|
||||||
self.channel_busy_slot = [False, False, False, False, False]
|
self.channel_busy_slot = [False, False, False, False, False]
|
||||||
self.is_codec2_traffic = False
|
self.is_codec2_traffic = False
|
||||||
|
@ -16,7 +16,12 @@ class STATES:
|
||||||
|
|
||||||
def set(self, key, value):
|
def set(self, key, value):
|
||||||
setattr(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):
|
def getAsJSON(self):
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
|
|
Loading…
Reference in a new issue