mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 10:04:33 +02:00
RADIO MANAGER - WIP initial release
This commit is contained in:
parent
9ad9e9b8c8
commit
543cbbdff8
|
@ -31,11 +31,12 @@ class RF:
|
|||
|
||||
log = structlog.get_logger("RF")
|
||||
|
||||
def __init__(self, config, event_manager, fft_queue, service_queue, states) -> None:
|
||||
def __init__(self, config, event_manager, fft_queue, service_queue, states, radio_manager) -> None:
|
||||
self.config = config
|
||||
self.service_queue = service_queue
|
||||
self.states = states
|
||||
self.event_manager = event_manager
|
||||
self.radio = radio_manager
|
||||
self.sampler_avg = 0
|
||||
self.buffer_avg = 0
|
||||
|
||||
|
@ -108,7 +109,6 @@ class RF:
|
|||
|
||||
# Initialize codec2, rig control, and data threads
|
||||
self.init_codec2()
|
||||
self.init_rig_control()
|
||||
self.init_data_threads()
|
||||
|
||||
return True
|
||||
|
@ -423,73 +423,3 @@ class RF:
|
|||
else:
|
||||
sd.play(audio_48k, blocksize=4096, blocking=True)
|
||||
return
|
||||
|
||||
def init_rig_control(self):
|
||||
# Check how we want to control the radio
|
||||
if self.radiocontrol == "rigctld":
|
||||
import rigctld as rig
|
||||
elif self.radiocontrol == "tci":
|
||||
self.radio = self.tci_module
|
||||
else:
|
||||
import rigdummy as rig
|
||||
|
||||
if not self.radiocontrol in ["tci"]:
|
||||
self.radio = rig.radio()
|
||||
self.radio.open_rig(
|
||||
rigctld_ip=self.rigctld_ip,
|
||||
rigctld_port=self.rigctld_port,
|
||||
)
|
||||
hamlib_thread = threading.Thread(
|
||||
target=self.update_rig_data, name="HAMLIB_THREAD", daemon=True
|
||||
)
|
||||
hamlib_thread.start()
|
||||
|
||||
hamlib_set_thread = threading.Thread(
|
||||
target=self.set_rig_data, name="HAMLIB_SET_THREAD", daemon=True
|
||||
)
|
||||
hamlib_set_thread.start()
|
||||
|
||||
def set_rig_data(self) -> None:
|
||||
"""
|
||||
Set rigctld parameters like frequency, mode
|
||||
THis needs to be processed in a queue
|
||||
"""
|
||||
while True:
|
||||
cmd = RIGCTLD_COMMAND_QUEUE.get()
|
||||
if cmd[0] == "set_frequency":
|
||||
# [1] = Frequency
|
||||
self.radio.set_frequency(cmd[1])
|
||||
if cmd[0] == "set_mode":
|
||||
# [1] = Mode
|
||||
self.radio.set_mode(cmd[1])
|
||||
|
||||
def update_rig_data(self) -> None:
|
||||
"""
|
||||
Request information about the current state of the radio via hamlib
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
# this looks weird, but is necessary for avoiding rigctld packet colission sock
|
||||
#threading.Event().wait(0.1)
|
||||
self.states.set("radio_status", self.radio.get_status())
|
||||
#threading.Event().wait(0.25)
|
||||
self.states.set("radio_frequency", self.radio.get_frequency())
|
||||
threading.Event().wait(0.1)
|
||||
self.states.set("radio_mode", self.radio.get_mode())
|
||||
threading.Event().wait(0.1)
|
||||
self.states.set("radio_bandwidth", self.radio.get_bandwidth())
|
||||
threading.Event().wait(0.1)
|
||||
if self.states.isTransmitting():
|
||||
self.radio_alc = self.radio.get_alc()
|
||||
threading.Event().wait(0.1)
|
||||
self.states.set("radio_rf_power", self.radio.get_level())
|
||||
threading.Event().wait(0.1)
|
||||
self.states.set("radio_strength", self.radio.get_strength())
|
||||
|
||||
except Exception as e:
|
||||
self.log.warning(
|
||||
"[MDM] error getting radio data",
|
||||
e=e,
|
||||
)
|
||||
threading.Event().wait(1)
|
||||
|
||||
|
|
56
modem/radio_manager.py
Normal file
56
modem/radio_manager.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
import rigctld
|
||||
import tci
|
||||
import rigdummy
|
||||
import time
|
||||
import threading
|
||||
class RadioManager:
|
||||
def __init__(self, config, state_manager, event_manager):
|
||||
self.config = config
|
||||
self.state_manager = state_manager
|
||||
self.event_manager = event_manager
|
||||
|
||||
self.radiocontrol = config['RADIO']['control']
|
||||
self.rigctld_ip = config['RIGCTLD']['ip']
|
||||
self.rigctld_port = config['RIGCTLD']['port']
|
||||
|
||||
self.refresh_rate = 1
|
||||
self.stop_event = threading.Event()
|
||||
self.update_thread = threading.Thread(target=self.update_parameters, daemon=True)
|
||||
self._init_rig_control()
|
||||
|
||||
def _init_rig_control(self):
|
||||
# Check how we want to control the radio
|
||||
if self.radiocontrol == "rigctld":
|
||||
self.radio = rigctld.radio(self.state_manager, hostname=self.rigctld_ip,port=self.rigctld_port)
|
||||
elif self.radiocontrol == "tci":
|
||||
raise NotImplementedError
|
||||
# self.radio = self.tci_module
|
||||
else:
|
||||
self.radio = rigdummy.radio()
|
||||
|
||||
self.update_thread.start()
|
||||
|
||||
def set_ptt(self, state):
|
||||
self.radio.set_ptt(state)
|
||||
|
||||
def set_frequency(self, frequency):
|
||||
self.radio.set_frequency(frequency)
|
||||
|
||||
def set_mode(self, mode):
|
||||
self.radio.set_mode(mode)
|
||||
|
||||
def update_parameters(self):
|
||||
while not self.stop_event.is_set():
|
||||
parameters = self.radio.get_parameters()
|
||||
self.state_manager.set("radio_frequency", parameters['frequency'])
|
||||
self.state_manager.set("radio_mode", parameters['mode'])
|
||||
self.state_manager.set("radio_bandwidth", parameters['bandwidth'])
|
||||
self.state_manager.set("radio_rf_power", parameters['rf'])
|
||||
|
||||
if self.state_manager.isTransmitting():
|
||||
self.radio_alc = parameters['alc']
|
||||
self.state_manager.set("radio_strength", parameters['strength'])
|
||||
time.sleep(self.refresh_rate)
|
||||
def stop(self):
|
||||
self.radio.disconnect()
|
||||
self.stop_event.set()
|
472
modem/rigctld.py
472
modem/rigctld.py
|
@ -1,345 +1,189 @@
|
|||
#!/usr/bin/env python3
|
||||
# class taken from darksidelemm
|
||||
# rigctl - https://github.com/darksidelemm/rotctld-web-gui/blob/master/rotatorgui.py#L35
|
||||
#
|
||||
# modified and adjusted to FreeDATA needs by DJ2LS
|
||||
|
||||
import contextlib
|
||||
import socket
|
||||
import structlog
|
||||
import threading
|
||||
|
||||
class radio:
|
||||
"""rigctld (hamlib) communication class"""
|
||||
|
||||
log = structlog.get_logger("radio (rigctld)")
|
||||
|
||||
def __init__(self, hostname="localhost", port=4532, poll_rate=5, timeout=5):
|
||||
"""Open a connection to rigctld, and test it for validity"""
|
||||
self.ptt_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.data_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
self.ptt_connected = False
|
||||
self.data_connected = False
|
||||
def __init__(self, states, hostname="localhost", port=4532, timeout=5):
|
||||
self.hostname = hostname
|
||||
self.port = port
|
||||
self.connection_attempts = 5
|
||||
self.timeout = timeout
|
||||
self.states = states
|
||||
|
||||
# class wide variable for some parameters
|
||||
self.bandwidth = ''
|
||||
self.frequency = ''
|
||||
self.mode = ''
|
||||
self.alc = ''
|
||||
self.strength = ''
|
||||
self.rf = ''
|
||||
self.connection = None
|
||||
self.connected = False
|
||||
|
||||
def open_rig(
|
||||
self,
|
||||
rigctld_ip,
|
||||
rigctld_port
|
||||
):
|
||||
"""
|
||||
self.parameters = {
|
||||
'frequency': '---',
|
||||
'mode': '---',
|
||||
'alc': '---',
|
||||
'strength': '---',
|
||||
'bandwidth': '---',
|
||||
'rf': '---',
|
||||
'ptt': False # Initial PTT state is set to False
|
||||
}
|
||||
|
||||
Args:
|
||||
rigctld_ip:
|
||||
rigctld_port:
|
||||
# connect to radio
|
||||
self.connect()
|
||||
|
||||
Returns:
|
||||
def connect(self):
|
||||
try:
|
||||
self.connection = socket.create_connection((self.hostname, self.port), timeout=self.timeout)
|
||||
self.connected = True
|
||||
self.states.set("radio_status", True)
|
||||
self.log.info(f"[RIGCTLD] Connected to rigctld at {self.hostname}:{self.port}")
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Failed to connect to rigctld: {err}")
|
||||
self.connected = False
|
||||
self.states.set("radio_status", False)
|
||||
|
||||
"""
|
||||
self.hostname = rigctld_ip
|
||||
self.port = int(rigctld_port)
|
||||
def disconnect(self):
|
||||
self.connected = False
|
||||
self.connection.close()
|
||||
del self.connection
|
||||
self.connection = None
|
||||
self.states.set("radio_status", False)
|
||||
self.parameters = {
|
||||
'frequency': '---',
|
||||
'mode': '---',
|
||||
'alc': '---',
|
||||
'strength': '---',
|
||||
'bandwidth': '---',
|
||||
'rf': '---',
|
||||
'ptt': False # Initial PTT state is set to False
|
||||
}
|
||||
|
||||
# _ptt_connect = self.ptt_connect()
|
||||
# _data_connect = self.data_connect()
|
||||
|
||||
ptt_thread = threading.Thread(target=self.ptt_connect, args=[], daemon=True)
|
||||
ptt_thread.start()
|
||||
|
||||
data_thread = threading.Thread(target=self.data_connect, args=[], daemon=True)
|
||||
data_thread.start()
|
||||
|
||||
# wait some time
|
||||
threading.Event().wait(0.5)
|
||||
|
||||
if self.ptt_connected and self.data_connected:
|
||||
self.log.debug("Rigctl DATA/PTT initialized")
|
||||
return True
|
||||
|
||||
self.log.error(
|
||||
"[RIGCTLD] Can't connect!", ip=self.hostname, port=self.port
|
||||
)
|
||||
return False
|
||||
|
||||
def ptt_connect(self):
|
||||
"""Connect to rigctld instance"""
|
||||
while True:
|
||||
|
||||
if not self.ptt_connected:
|
||||
try:
|
||||
self.ptt_connection = socket.create_connection((self.hostname, self.port))
|
||||
self.ptt_connected = True
|
||||
self.log.info(
|
||||
"[RIGCTLD] Connected PTT instance to rigctld!", ip=self.hostname, port=self.port
|
||||
)
|
||||
except Exception as err:
|
||||
# ConnectionRefusedError: [Errno 111] Connection refused
|
||||
self.close_rig()
|
||||
self.log.warning(
|
||||
"[RIGCTLD] PTT Reconnect...",
|
||||
ip=self.hostname,
|
||||
port=self.port,
|
||||
e=err,
|
||||
)
|
||||
|
||||
threading.Event().wait(0.5)
|
||||
|
||||
def data_connect(self):
|
||||
"""Connect to rigctld instance"""
|
||||
while True:
|
||||
if not self.data_connected:
|
||||
try:
|
||||
self.data_connection = socket.create_connection((self.hostname, self.port))
|
||||
self.data_connected = True
|
||||
self.log.info(
|
||||
"[RIGCTLD] Connected DATA instance to rigctld!", ip=self.hostname, port=self.port
|
||||
)
|
||||
except Exception as err:
|
||||
# ConnectionRefusedError: [Errno 111] Connection refused
|
||||
self.close_rig()
|
||||
self.log.warning(
|
||||
"[RIGCTLD] DATA Reconnect...",
|
||||
ip=self.hostname,
|
||||
port=self.port,
|
||||
e=err,
|
||||
)
|
||||
threading.Event().wait(0.5)
|
||||
|
||||
def close_rig(self):
|
||||
""" """
|
||||
self.ptt_sock.close()
|
||||
self.data_sock.close()
|
||||
self.ptt_connected = False
|
||||
self.data_connected = False
|
||||
|
||||
def send_ptt_command(self, command, expect_answer) -> bytes:
|
||||
"""Send a command to the connected rotctld instance,
|
||||
and return the return value.
|
||||
|
||||
Args:
|
||||
command:
|
||||
|
||||
"""
|
||||
if self.ptt_connected:
|
||||
def send_command(self, command) -> str:
|
||||
if self.connected:
|
||||
try:
|
||||
self.ptt_connection.sendall(command + b"\n")
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
"[RIGCTLD] Command not executed!",
|
||||
command=command,
|
||||
ip=self.hostname,
|
||||
port=self.port,
|
||||
)
|
||||
self.ptt_connected = False
|
||||
return b""
|
||||
|
||||
def send_data_command(self, command, expect_answer) -> bytes:
|
||||
"""Send a command to the connected rotctld instance,
|
||||
and return the return value.
|
||||
|
||||
Args:
|
||||
command:
|
||||
|
||||
"""
|
||||
if self.data_connected:
|
||||
self.data_connection.setblocking(False)
|
||||
#Allow a little more time for a response from rigctld before generating a timeout, seems to have no ill effects on a well behaving setup and fixes Issue #373
|
||||
self.data_connection.settimeout(0.30)
|
||||
try:
|
||||
self.data_connection.sendall(command + b"\n")
|
||||
|
||||
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
"[RIGCTLD] Command not executed!",
|
||||
command=command,
|
||||
ip=self.hostname,
|
||||
port=self.port,
|
||||
)
|
||||
self.data_connected = False
|
||||
|
||||
try:
|
||||
# recv seems to be blocking so in case of ptt we don't need the response
|
||||
# maybe this speeds things up and avoids blocking states
|
||||
recv = True
|
||||
data = b''
|
||||
|
||||
while recv:
|
||||
try:
|
||||
|
||||
data = self.data_connection.recv(4800)
|
||||
|
||||
except socket.timeout:
|
||||
recv = False
|
||||
|
||||
return data
|
||||
|
||||
# return self.data_connection.recv(64) if expect_answer else True
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
"[RIGCTLD] No command response!",
|
||||
command=command,
|
||||
ip=self.hostname,
|
||||
port=self.port,
|
||||
)
|
||||
self.data_connected = False
|
||||
return b""
|
||||
|
||||
def get_status(self):
|
||||
""" """
|
||||
return True if self.data_connected and self.ptt_connected else False
|
||||
|
||||
def get_level(self):
|
||||
try:
|
||||
data = self.send_data_command(b"l RF", True)
|
||||
data = data.split(b"\n")
|
||||
rf = data[0].decode("utf-8")
|
||||
if 'RPRT' not in rf:
|
||||
try:
|
||||
self.rf = str(rf)
|
||||
except ValueError:
|
||||
self.rf = str(rf)
|
||||
|
||||
return self.rf
|
||||
except Exception:
|
||||
return self.rf
|
||||
|
||||
def get_strength(self):
|
||||
try:
|
||||
data = self.send_data_command(b"l STRENGTH", True)
|
||||
data = data.split(b"\n")
|
||||
strength = data[0].decode("utf-8")
|
||||
if 'RPRT' not in strength:
|
||||
try:
|
||||
self.strength = str(strength)
|
||||
except ValueError:
|
||||
self.strength = str(strength)
|
||||
|
||||
return self.strength
|
||||
except Exception:
|
||||
return self.strength
|
||||
|
||||
def get_alc(self):
|
||||
try:
|
||||
data = self.send_data_command(b"l ALC", True)
|
||||
data = data.split(b"\n")
|
||||
alc = data[0].decode("utf-8")
|
||||
if 'RPRT' not in alc:
|
||||
try:
|
||||
alc = float(alc)
|
||||
except ValueError:
|
||||
self.alc = 0.0
|
||||
|
||||
return self.alc
|
||||
except Exception:
|
||||
return self.alc
|
||||
|
||||
def get_mode(self):
|
||||
""" """
|
||||
try:
|
||||
data = self.send_data_command(b"m", True)
|
||||
data = data.split(b"\n")
|
||||
data = data[0].decode("utf-8")
|
||||
if 'RPRT' not in data:
|
||||
try:
|
||||
data = int(data)
|
||||
except ValueError:
|
||||
self.mode = str(data)
|
||||
|
||||
return self.mode
|
||||
except Exception:
|
||||
return self.mode
|
||||
|
||||
def get_bandwidth(self):
|
||||
""" """
|
||||
try:
|
||||
data = self.send_data_command(b"m", True)
|
||||
data = data.split(b"\n")
|
||||
data = data[1].decode("utf-8")
|
||||
|
||||
if 'RPRT' not in data and data not in ['']:
|
||||
with contextlib.suppress(ValueError):
|
||||
self.bandwidth = int(data)
|
||||
return self.bandwidth
|
||||
except Exception:
|
||||
return self.bandwidth
|
||||
|
||||
def get_frequency(self):
|
||||
""" """
|
||||
try:
|
||||
data = self.send_data_command(b"f", True)
|
||||
data = data.decode("utf-8")
|
||||
if 'RPRT' not in data and data not in [0, '0', '']:
|
||||
with contextlib.suppress(ValueError):
|
||||
data = int(data)
|
||||
# make sure we have a frequency and not bandwidth
|
||||
if data >= 10000:
|
||||
self.frequency = data
|
||||
return self.frequency
|
||||
except Exception:
|
||||
return self.frequency
|
||||
|
||||
def get_ptt(self):
|
||||
""" """
|
||||
try:
|
||||
return self.send_data_command(b"t", True)
|
||||
except Exception:
|
||||
return False
|
||||
self.connection.sendall(command.encode('utf-8') + b"\n")
|
||||
response = self.connection.recv(1024)
|
||||
return response.decode('utf-8').strip()
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Error sending command to rigctld: {err}")
|
||||
self.connected = False
|
||||
return ""
|
||||
|
||||
def set_ptt(self, state):
|
||||
"""
|
||||
"""Set the PTT (Push-to-Talk) state.
|
||||
|
||||
Args:
|
||||
state:
|
||||
state (bool): True to enable PTT, False to disable.
|
||||
|
||||
Returns:
|
||||
|
||||
bool: True if the PTT state was set successfully, False otherwise.
|
||||
"""
|
||||
try:
|
||||
if state:
|
||||
self.send_ptt_command(b"T 1", False)
|
||||
else:
|
||||
self.send_ptt_command(b"T 0", False)
|
||||
return state
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def set_frequency(self, frequency):
|
||||
"""
|
||||
|
||||
Args:
|
||||
frequency:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
try:
|
||||
command = bytes(f"F {frequency}", "utf-8")
|
||||
self.send_data_command(command, False)
|
||||
except Exception:
|
||||
return False
|
||||
if self.connected:
|
||||
try:
|
||||
if state:
|
||||
self.send_command('T 1') # Enable PTT
|
||||
else:
|
||||
self.send_command('T 0') # Disable PTT
|
||||
self.parameters['ptt'] = state # Update PTT state in parameters
|
||||
return True
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Error setting PTT state: {err}")
|
||||
self.connected = False
|
||||
return False
|
||||
|
||||
def set_mode(self, mode):
|
||||
"""
|
||||
"""Set the mode.
|
||||
|
||||
Args:
|
||||
mode:
|
||||
mode (str): The mode to set.
|
||||
|
||||
Returns:
|
||||
|
||||
bool: True if the mode was set successfully, False otherwise.
|
||||
"""
|
||||
try:
|
||||
command = bytes(f"M {mode} {self.bandwidth}", "utf-8")
|
||||
self.send_data_command(command, False)
|
||||
except Exception:
|
||||
return False
|
||||
if self.connected:
|
||||
try:
|
||||
command = f"M {mode}"
|
||||
self.send_command(command)
|
||||
self.parameters['mode'] = mode
|
||||
return True
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Error setting mode: {err}")
|
||||
self.connected = False
|
||||
return False
|
||||
|
||||
def set_frequency(self, frequency):
|
||||
"""Set the frequency.
|
||||
|
||||
Args:
|
||||
frequency (str): The frequency to set.
|
||||
|
||||
Returns:
|
||||
bool: True if the frequency was set successfully, False otherwise.
|
||||
"""
|
||||
if self.connected:
|
||||
try:
|
||||
command = f"F {frequency}"
|
||||
self.send_command(command)
|
||||
self.parameters['frequency'] = frequency
|
||||
return True
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Error setting frequency: {err}")
|
||||
self.connected = False
|
||||
return False
|
||||
|
||||
def set_bandwidth(self, bandwidth):
|
||||
"""Set the bandwidth.
|
||||
|
||||
Args:
|
||||
bandwidth (str): The bandwidth to set.
|
||||
|
||||
Returns:
|
||||
bool: True if the bandwidth was set successfully, False otherwise.
|
||||
"""
|
||||
if self.connected:
|
||||
try:
|
||||
command = f"M {self.parameters['mode']} {bandwidth}"
|
||||
self.send_command(command)
|
||||
self.parameters['bandwidth'] = bandwidth
|
||||
return True
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Error setting bandwidth: {err}")
|
||||
self.connected = False
|
||||
return False
|
||||
|
||||
def set_rf(self, rf):
|
||||
"""Set the RF.
|
||||
|
||||
Args:
|
||||
rf (str): The RF to set.
|
||||
|
||||
Returns:
|
||||
bool: True if the RF was set successfully, False otherwise.
|
||||
"""
|
||||
if self.connected:
|
||||
try:
|
||||
command = f"l RF {rf}"
|
||||
self.send_command(command)
|
||||
self.parameters['rf'] = rf
|
||||
return True
|
||||
except Exception as err:
|
||||
self.log.warning(f"[RIGCTLD] Error setting RF: {err}")
|
||||
self.connected = False
|
||||
return False
|
||||
|
||||
def get_parameters(self):
|
||||
if not self.connected:
|
||||
self.connect()
|
||||
|
||||
if self.connected:
|
||||
self.parameters['frequency'] = self.send_command('f')
|
||||
response = self.send_command(
|
||||
'm').strip() # Get the mode/bandwidth response and remove leading/trailing spaces
|
||||
mode, bandwidth = response.split('\n', 1) # Split the response into mode and bandwidth
|
||||
|
||||
self.parameters['mode'] = mode
|
||||
self.parameters['bandwidth'] = bandwidth
|
||||
|
||||
self.parameters['alc'] = self.send_command('l ALC')
|
||||
self.parameters['strength'] = self.send_command('l STRENGTH')
|
||||
self.parameters['rf'] = self.send_command('l RF')
|
||||
|
||||
"""Return the latest fetched parameters."""
|
||||
return self.parameters
|
||||
|
|
|
@ -1,13 +1,30 @@
|
|||
hamlib_version = 0
|
||||
|
||||
|
||||
class radio:
|
||||
""" """
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
self.parameters = {
|
||||
'frequency': '---',
|
||||
'mode': '---',
|
||||
'alc': '---',
|
||||
'strength': '---',
|
||||
'bandwidth': '---',
|
||||
'rf': '---',
|
||||
'ptt': False # Initial PTT state is set to False
|
||||
}
|
||||
|
||||
def open_rig(self, **kwargs):
|
||||
def connect(self, **kwargs):
|
||||
"""
|
||||
|
||||
Args:
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
def disconnect(self, **kwargs):
|
||||
"""
|
||||
|
||||
Args:
|
||||
|
@ -98,3 +115,7 @@ class radio:
|
|||
def close_rig(self):
|
||||
""" """
|
||||
return
|
||||
|
||||
|
||||
def get_parameters(self):
|
||||
return self.parameters
|
|
@ -18,6 +18,7 @@ import command_feq
|
|||
import command_test
|
||||
import command_arq_raw
|
||||
import event_manager
|
||||
import radio_manager
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
|
@ -58,6 +59,7 @@ app.state_manager = state_manager.StateManager(app.state_queue)
|
|||
# start service manager
|
||||
app.service_manager = service_manager.SM(app)
|
||||
|
||||
|
||||
# start modem service
|
||||
app.modem_service.put("start")
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import audio
|
|||
import ujson as json
|
||||
import explorer
|
||||
import beacon
|
||||
import radio_manager
|
||||
|
||||
|
||||
class SM:
|
||||
|
@ -15,11 +16,12 @@ class SM:
|
|||
self.modem = False
|
||||
self.beacon = False
|
||||
self.explorer = False
|
||||
self.radio = False
|
||||
self.app = app
|
||||
self.config = self.app.config_manager.read()
|
||||
self.modem_fft = app.modem_fft
|
||||
self.modem_service = app.modem_service
|
||||
self.states = app.state_manager
|
||||
self.state_manager = app.state_manager
|
||||
self.event_manager = app.event_manager
|
||||
|
||||
|
||||
|
@ -34,22 +36,31 @@ class SM:
|
|||
if cmd in ['start'] and not self.modem:
|
||||
self.log.info("------------------ FreeDATA ------------------")
|
||||
self.log.info("------------------ MODEM ------------------")
|
||||
self.config = self.app.config_manager.read()
|
||||
self.start_radio_manager()
|
||||
self.start_modem()
|
||||
self.start_explorer_publishing()
|
||||
|
||||
elif cmd in ['stop'] and self.modem:
|
||||
self.stop_modem()
|
||||
self.stop_explorer_publishing()
|
||||
self.stop_radio_manager()
|
||||
# we need to wait a bit for avoiding a portaudio crash
|
||||
threading.Event().wait(0.5)
|
||||
|
||||
elif cmd in ['restart']:
|
||||
self.stop_modem()
|
||||
self.stop_explorer_publishing()
|
||||
self.stop_radio_manager()
|
||||
# we need to wait a bit for avoiding a portaudio crash
|
||||
threading.Event().wait(0.5)
|
||||
|
||||
self.config = self.app.config_manager.read()
|
||||
self.start_radio_manager()
|
||||
|
||||
if self.start_modem():
|
||||
self.event_manager.modem_restarted()
|
||||
self.start_explorer_publishing()
|
||||
elif cmd in ['start_beacon']:
|
||||
self.start_beacon()
|
||||
|
||||
|
@ -59,37 +70,34 @@ class SM:
|
|||
|
||||
|
||||
else:
|
||||
self.log.warning("[SVC] modem command processing failed", cmd=cmd, state=self.states.is_modem_running)
|
||||
self.log.warning("[SVC] modem command processing failed", cmd=cmd, state=self.state_manager.is_modem_running)
|
||||
|
||||
|
||||
def start_modem(self):
|
||||
# read config
|
||||
self.config = self.app.config_manager.read()
|
||||
|
||||
if self.states.is_modem_running:
|
||||
if self.state_manager.is_modem_running:
|
||||
self.log.warning("modem already running")
|
||||
return False
|
||||
|
||||
# test audio devices
|
||||
audio_test = self.test_audio()
|
||||
|
||||
if False in audio_test or None in audio_test or self.states.is_modem_running:
|
||||
if False in audio_test or None in audio_test or self.state_manager.is_modem_running:
|
||||
self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1])
|
||||
self.states.set("is_modem_running", False)
|
||||
self.state_manager.set("is_modem_running", False)
|
||||
self.event_manager.modem_failed()
|
||||
return False
|
||||
|
||||
self.log.info("starting modem....")
|
||||
self.modem = modem.RF(self.config, self.event_manager, self.modem_fft, self.modem_service, self.states)
|
||||
self.modem = modem.RF(self.config, self.event_manager, self.modem_fft, self.modem_service, self.state_manager, self.radio)
|
||||
|
||||
self.frame_dispatcher = frame_dispatcher.DISPATCHER(self.config,
|
||||
self.event_manager,
|
||||
self.states,
|
||||
self.state_manager,
|
||||
self.modem)
|
||||
self.frame_dispatcher.start()
|
||||
|
||||
self.event_manager.modem_started()
|
||||
self.states.set("is_modem_running", True)
|
||||
self.state_manager.set("is_modem_running", True)
|
||||
self.modem.start_modem()
|
||||
|
||||
return True
|
||||
|
@ -98,7 +106,7 @@ class SM:
|
|||
self.log.info("stopping modem....")
|
||||
del self.modem
|
||||
self.modem = False
|
||||
self.states.set("is_modem_running", False)
|
||||
self.state_manager.set("is_modem_running", False)
|
||||
self.event_manager.modem_stopped()
|
||||
|
||||
def test_audio(self):
|
||||
|
@ -113,7 +121,7 @@ class SM:
|
|||
return [False, False]
|
||||
|
||||
def start_beacon(self):
|
||||
self.beacon = beacon.Beacon(self.config, self.states, self.event_manager, self.log, self.modem)
|
||||
self.beacon = beacon.Beacon(self.config, self.state_manager, self.event_manager, self.log, self.modem)
|
||||
self.beacon.start()
|
||||
|
||||
def stop_beacon(self):
|
||||
|
@ -123,10 +131,17 @@ class SM:
|
|||
try:
|
||||
# optionally start explorer module
|
||||
if self.config['STATION']['enable_explorer']:
|
||||
self.explorer = explorer.explorer(self.app, self.config, self.states)
|
||||
self.explorer = explorer.explorer(self.app, self.config, self.state_manager)
|
||||
except Exception as e:
|
||||
self.log.warning("[EXPLORER] Publishing not started because of error", e=e)
|
||||
|
||||
def stop_explorer_publishing(self):
|
||||
if self.config['STATION']['enable_explorer']:
|
||||
del self.explorer
|
||||
del self.explorer
|
||||
|
||||
def start_radio_manager(self):
|
||||
self.radio = radio_manager.RadioManager(self.config, self.state_manager, self.event_manager)
|
||||
|
||||
def stop_radio_manager(self):
|
||||
self.radio.stop()
|
||||
del self.radio
|
|
@ -12,7 +12,7 @@ from command_ping import PingCommand
|
|||
from command_cq import CQCommand
|
||||
import modem
|
||||
import frame_handler
|
||||
|
||||
from radio_manager import RadioManager
|
||||
|
||||
class TestProtocols(unittest.TestCase):
|
||||
|
||||
|
@ -27,9 +27,10 @@ class TestProtocols(unittest.TestCase):
|
|||
cls.event_queue = queue.Queue()
|
||||
cls.event_manager = EventManager([cls.event_queue])
|
||||
|
||||
cls.radio_manager = RadioManager(cls.config, cls.state_manager, cls.event_manager)
|
||||
cls.modem_transmit_queue = queue.Queue()
|
||||
|
||||
cls.modem = modem.RF(cls.config, cls.event_queue, queue.Queue(), queue.Queue(), cls.state_manager)
|
||||
cls.modem = modem.RF(cls.config, cls.event_queue, queue.Queue(), queue.Queue(), cls.state_manager, cls.radio_manager)
|
||||
modem.TESTMODE = True
|
||||
frame_handler.TESTMODE = True
|
||||
|
||||
|
|
Loading…
Reference in a new issue