FreeDATA/modem/service_manager.py

147 lines
5.1 KiB
Python
Raw Normal View History

2023-11-09 21:11:53 +00:00
import threading
2023-11-23 09:14:11 +00:00
import frame_dispatcher
2023-11-09 21:11:53 +00:00
import modem
import structlog
import audio
2023-11-12 21:35:10 +00:00
import ujson as json
2023-11-12 22:22:53 +00:00
import explorer
2023-12-21 16:47:48 +00:00
import beacon
2024-01-12 14:51:23 +00:00
import radio_manager
2023-11-12 21:35:10 +00:00
2023-11-09 21:11:53 +00:00
class SM:
def __init__(self, app):
self.log = structlog.get_logger("service")
self.modem = False
2023-12-21 16:47:48 +00:00
self.beacon = False
self.explorer = False
2024-01-12 14:51:23 +00:00
self.radio = False
2023-11-19 08:56:00 +00:00
self.app = app
self.config = self.app.config_manager.read()
2023-11-09 21:11:53 +00:00
self.modem_fft = app.modem_fft
self.modem_service = app.modem_service
2024-01-12 14:51:23 +00:00
self.state_manager = app.state_manager
self.event_manager = app.event_manager
2023-11-09 21:11:53 +00:00
runner_thread = threading.Thread(
target=self.runner, name="runner thread", daemon=True
)
runner_thread.start()
def runner(self):
while True:
cmd = self.modem_service.get()
if cmd in ['start'] and not self.modem:
2023-11-12 21:35:10 +00:00
self.log.info("------------------ FreeDATA ------------------")
self.log.info("------------------ MODEM ------------------")
2024-01-12 14:51:23 +00:00
self.config = self.app.config_manager.read()
self.start_radio_manager()
2023-11-12 21:35:10 +00:00
self.start_modem()
self.start_explorer_publishing()
2023-11-12 21:35:10 +00:00
elif cmd in ['stop'] and self.modem:
self.stop_modem()
self.stop_explorer_publishing()
2024-01-12 14:51:23 +00:00
self.stop_radio_manager()
2023-11-12 21:35:10 +00:00
# we need to wait a bit for avoiding a portaudio crash
threading.Event().wait(0.5)
2023-11-12 18:56:15 +00:00
2023-11-12 21:35:10 +00:00
elif cmd in ['restart']:
self.stop_modem()
self.stop_explorer_publishing()
2024-01-12 14:51:23 +00:00
self.stop_radio_manager()
2023-11-12 21:35:10 +00:00
# we need to wait a bit for avoiding a portaudio crash
threading.Event().wait(0.5)
2024-01-12 14:51:23 +00:00
self.config = self.app.config_manager.read()
self.start_radio_manager()
2023-11-12 21:35:10 +00:00
if self.start_modem():
self.event_manager.modem_restarted()
2024-01-12 14:51:23 +00:00
self.start_explorer_publishing()
2023-12-21 16:47:48 +00:00
elif cmd in ['start_beacon']:
self.start_beacon()
elif cmd in ['stop_beacon']:
self.stop_beacon()
2023-11-09 21:11:53 +00:00
else:
2024-01-12 14:51:23 +00:00
self.log.warning("[SVC] modem command processing failed", cmd=cmd, state=self.state_manager.is_modem_running)
2023-11-12 21:35:10 +00:00
def start_modem(self):
2024-01-12 14:51:23 +00:00
if self.state_manager.is_modem_running:
2023-11-26 13:51:58 +00:00
self.log.warning("modem already running")
return False
2023-11-19 08:56:00 +00:00
# test audio devices
2023-11-12 21:35:10 +00:00
audio_test = self.test_audio()
2023-11-19 08:56:00 +00:00
2024-01-12 14:51:23 +00:00
if False in audio_test or None in audio_test or self.state_manager.is_modem_running:
2023-11-12 21:35:10 +00:00
self.log.warning("starting modem failed", input_test=audio_test[0], output_test=audio_test[1])
2024-01-12 14:51:23 +00:00
self.state_manager.set("is_modem_running", False)
self.event_manager.modem_failed()
2023-11-12 21:35:10 +00:00
return False
2023-11-26 13:51:58 +00:00
self.log.info("starting modem....")
2024-01-12 14:51:23 +00:00
self.modem = modem.RF(self.config, self.event_manager, self.modem_fft, self.modem_service, self.state_manager, self.radio)
2023-11-26 13:51:58 +00:00
2023-11-29 16:35:23 +00:00
self.frame_dispatcher = frame_dispatcher.DISPATCHER(self.config,
self.event_manager,
2024-01-12 14:51:23 +00:00
self.state_manager,
self.modem)
2023-11-26 13:51:58 +00:00
self.frame_dispatcher.start()
self.event_manager.modem_started()
2024-01-12 14:51:23 +00:00
self.state_manager.set("is_modem_running", True)
2023-11-29 16:35:23 +00:00
self.modem.start_modem()
2023-11-26 13:51:58 +00:00
return True
2023-11-12 21:35:10 +00:00
def stop_modem(self):
self.log.info("stopping modem....")
del self.modem
self.modem = False
2024-01-12 14:51:23 +00:00
self.state_manager.set("is_modem_running", False)
self.event_manager.modem_stopped()
2023-11-12 21:35:10 +00:00
def test_audio(self):
2024-01-05 14:10:46 +00:00
try:
audio_test = audio.test_audio_devices(self.config['AUDIO']['input_device'],
self.config['AUDIO']['output_device'])
self.log.info("tested audio devices", result=audio_test)
2023-12-21 16:47:48 +00:00
2024-01-05 14:10:46 +00:00
return audio_test
except Exception as e:
self.log.error("Error testing audio devices", e=e)
return [False, False]
2023-12-21 16:47:48 +00:00
def start_beacon(self):
2024-01-12 14:51:23 +00:00
self.beacon = beacon.Beacon(self.config, self.state_manager, self.event_manager, self.log, self.modem)
2023-12-21 16:47:48 +00:00
self.beacon.start()
def stop_beacon(self):
2024-01-11 13:56:45 +00:00
self.beacon.stop()
2024-01-05 14:10:46 +00:00
def start_explorer_publishing(self):
try:
# optionally start explorer module
if self.config['STATION']['enable_explorer']:
2024-01-12 14:51:23 +00:00
self.explorer = explorer.explorer(self.app, self.config, self.state_manager)
2024-01-05 14:10:46 +00:00
except Exception as e:
self.log.warning("[EXPLORER] Publishing not started because of error", e=e)
def stop_explorer_publishing(self):
2024-01-12 13:08:07 +00:00
if self.config['STATION']['enable_explorer']:
2024-01-12 14:51:23 +00:00
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