94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
import logging
|
|
import shutil
|
|
import subprocess
|
|
import threading
|
|
import time
|
|
from BotResources import DEFAULT_RADIO_SETTINGS
|
|
|
|
|
|
class OP25Handler(threading.Thread):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.OP25Dir: str = "/home/pi/op25/op25/gr-op25_repeater/apps"
|
|
self.OP25EXE: str = shutil.which("/home/pi/op25/op25/gr-op25_repeater/apps/rx.py")
|
|
self.OP25Proc = None
|
|
|
|
self.Frequency = DEFAULT_RADIO_SETTINGS['freq']
|
|
|
|
self.HTTP_ENABLED = False
|
|
|
|
self.Start_OP25 = False
|
|
|
|
self.Stop_OP25 = False
|
|
|
|
self.Output_Device_Name = None
|
|
|
|
self.logger = logging.getLogger("Discord_Radio_Bot.OP25Handler")
|
|
|
|
def run(self) -> None:
|
|
while True:
|
|
if self.Start_OP25:
|
|
self.open_op25()
|
|
|
|
self.Start_OP25 = False
|
|
self.Stop_OP25 = False
|
|
|
|
while not self.Stop_OP25:
|
|
time.sleep(1)
|
|
|
|
self.close_op25()
|
|
|
|
time.sleep(.5)
|
|
|
|
def set_op25_parameters(self, _frequency: str = False, _http_enabled: bool = True, _start: bool = False,
|
|
_stop: bool = False, _output_device_name: str = None):
|
|
if _frequency:
|
|
self.Frequency = _frequency
|
|
|
|
if _start:
|
|
self.Start_OP25 = _start
|
|
|
|
if _stop:
|
|
self.Stop_OP25 = _stop
|
|
|
|
if _http_enabled:
|
|
self.HTTP_ENABLED = _http_enabled
|
|
|
|
if _output_device_name:
|
|
self.Output_Device_Name = _output_device_name
|
|
|
|
def open_op25(self):
|
|
if self.OP25Proc is not None:
|
|
self.close_op25()
|
|
|
|
p25_kwargs = [f"./rx.py", "--args", "rtl", "-N", "LNA:49", "-s", "200000", "-o", "25600", "-w", "-U", "-O",
|
|
f"{self.Output_Device_Name}", "-f", f"{self.Frequency}e6", "-X", "-2"]
|
|
|
|
self.logger.info(f"Starting OP25")
|
|
# Change the interpreter's working directory (idr why)
|
|
if self.HTTP_ENABLED:
|
|
p25_kwargs.extend(["-l", "http:0.0.0.0:8080"])
|
|
|
|
self.logger.debug(f"OP25 Keyword Args: {p25_kwargs}")
|
|
|
|
self.OP25Proc = subprocess.Popen(p25_kwargs, executable=self.OP25EXE, shell=False, cwd=self.OP25Dir,
|
|
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
|
|
def close_op25(self):
|
|
self.logger.info(f"Closing OP25")
|
|
try:
|
|
self.OP25Proc.kill()
|
|
|
|
seconds_waited = 0
|
|
while self.OP25Proc.poll() is None:
|
|
# Terminate the process every 5 seconds
|
|
if seconds_waited % 5 == 0:
|
|
self.logger.info("Terminating OP25")
|
|
self.OP25Proc.terminate()
|
|
time.sleep(1)
|
|
self.logger.debug(f"Waited {seconds_waited} seconds")
|
|
seconds_waited += 1
|
|
|
|
except Exception as e:
|
|
self.logger.error(e)
|