mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
..and some other changes to the gui so its compatible again with the latest socket commands. The rx buffer has now a unique id, and new structure. Also all messages and files will be saved to the same buffer. All commands which will be sent to the tnc or dameon are now written in lowercase
254 lines
9 KiB
Python
Executable file
254 lines
9 KiB
Python
Executable file
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
daemon.py
|
|
|
|
Author: DJ2LS, January 2022
|
|
|
|
"""
|
|
|
|
import argparse
|
|
import threading
|
|
import socketserver
|
|
import time
|
|
import sys
|
|
import subprocess
|
|
import ujson as json
|
|
import psutil
|
|
import serial.tools.list_ports
|
|
import static
|
|
import crcengine
|
|
import re
|
|
import structlog
|
|
import log_handler
|
|
import helpers
|
|
import os
|
|
import queue
|
|
import audio
|
|
import sock
|
|
|
|
|
|
class DAEMON():
|
|
def __init__(self):
|
|
|
|
# load crc engine
|
|
self.crc_algorithm = crcengine.new('crc16-ccitt-false') # load crc8 library
|
|
|
|
self.daemon_queue = sock.DAEMON_QUEUE
|
|
update_audio_devices = threading.Thread(target=self.update_audio_devices, name="UPDATE_AUDIO_DEVICES")
|
|
update_audio_devices.start()
|
|
|
|
update_serial_devices = threading.Thread(target=self.update_serial_devices, name="UPDATE_SERIAL_DEVICES")
|
|
update_serial_devices.start()
|
|
|
|
worker = threading.Thread(target=self.worker, name="WORKER")
|
|
worker.start()
|
|
|
|
|
|
def update_audio_devices(self):
|
|
while 1:
|
|
static.AUDIO_INPUT_DEVICES, static.AUDIO_OUTPUT_DEVICES = audio.get_input_devices()
|
|
time.sleep(1)
|
|
|
|
def update_serial_devices(self):
|
|
while 1:
|
|
serial_devices = []
|
|
ports = serial.tools.list_ports.comports()
|
|
for port, desc, hwid in ports:
|
|
|
|
# calculate hex of hwid if we have unique names
|
|
crc_hwid = self.crc_algorithm(bytes(hwid, encoding='utf-8'))
|
|
crc_hwid = crc_hwid.to_bytes(2, byteorder='big')
|
|
crc_hwid = crc_hwid.hex()
|
|
description = desc + ' [' + crc_hwid + ']'
|
|
serial_devices.append({"port": str(port), "description": str(description) })
|
|
|
|
static.SERIAL_DEVICES = serial_devices
|
|
time.sleep(1)
|
|
|
|
|
|
def worker(self):
|
|
while 1:
|
|
|
|
data = self.daemon_queue.get()
|
|
|
|
# data[1] mycall
|
|
# data[2] mygrid
|
|
# data[3] rx_audio
|
|
# data[4] tx_audio
|
|
# data[5] devicename
|
|
# data[6] deviceport
|
|
# data[7] serialspeed
|
|
# data[8] pttprotocol
|
|
# data[9] pttport
|
|
# data[10] data_bits
|
|
# data[11] stop_bits
|
|
# data[12] handshake
|
|
# data[13] radiocontrol
|
|
# data[14] rigctld_ip
|
|
# data[15] rigctld_port
|
|
if data[0] == 'STARTTNC':
|
|
structlog.get_logger("structlog").warning("[DMN] Starting TNC", rig=data[5], port=data[6])
|
|
|
|
# list of parameters, necessary for running subprocess command as a list
|
|
options = []
|
|
options.append('--mycall')
|
|
options.append(data[1])
|
|
|
|
options.append('--mygrid')
|
|
options.append(data[2])
|
|
|
|
options.append('--rx')
|
|
options.append(data[3])
|
|
|
|
options.append('--tx')
|
|
options.append(data[4])
|
|
|
|
options.append('--devicename')
|
|
options.append(data[5])
|
|
|
|
options.append('--deviceport')
|
|
options.append(data[6])
|
|
|
|
options.append('--serialspeed')
|
|
options.append(data[7])
|
|
|
|
options.append('--pttprotocol')
|
|
options.append(data[8])
|
|
|
|
options.append('--pttport')
|
|
options.append(data[9])
|
|
|
|
options.append('--data_bits')
|
|
options.append(data[10])
|
|
|
|
options.append('--stop_bits')
|
|
options.append(data[11])
|
|
|
|
options.append('--handshake')
|
|
options.append(data[12])
|
|
|
|
options.append('--radiocontrol')
|
|
options.append(data[13])
|
|
|
|
options.append('--rigctld_ip')
|
|
options.append(data[14])
|
|
|
|
options.append('--rigctld_port')
|
|
options.append(data[15])
|
|
|
|
# try running tnc from binary, else run from source
|
|
# this helps running the tnc in a developer environment
|
|
try:
|
|
command = []
|
|
if sys.platform == 'linux' or sys.platform == 'darwin':
|
|
command.append('./tnc')
|
|
elif sys.platform == 'win32' or sys.platform == 'win64':
|
|
command.append('tnc.exe')
|
|
|
|
command += options
|
|
p = subprocess.Popen(command)
|
|
structlog.get_logger("structlog").info("[DMN] TNC started", path="binary")
|
|
except:
|
|
command = []
|
|
if sys.platform == 'linux' or sys.platform == 'darwin':
|
|
command.append('python3')
|
|
elif sys.platform == 'win32' or sys.platform == 'win64':
|
|
command.append('python')
|
|
|
|
command.append('main.py')
|
|
command += options
|
|
p = subprocess.Popen(command)
|
|
structlog.get_logger("structlog").info("[DMN] TNC started", path="source")
|
|
|
|
static.TNCPROCESS = p # .pid
|
|
static.TNCSTARTED = True
|
|
|
|
# data[1] devicename
|
|
# data[2] deviceport
|
|
# data[3] serialspeed
|
|
# data[4] pttprotocol
|
|
# data[5] pttport
|
|
# data[6] data_bits
|
|
# data[7] stop_bits
|
|
# data[8] handshake
|
|
# data[9] radiocontrol
|
|
# data[10] rigctld_ip
|
|
# data[11] rigctld_port
|
|
if data[0] == 'TEST_HAMLIB':
|
|
|
|
devicename = data[1]
|
|
deviceport = data[2]
|
|
serialspeed = data[3]
|
|
pttprotocol = data[4]
|
|
pttport = data[5]
|
|
data_bits = data[6]
|
|
stop_bits = data[7]
|
|
handshake = data[8]
|
|
radiocontrol = data[9]
|
|
rigctld_ip = data[10]
|
|
rigctld_port = data[11]
|
|
|
|
|
|
# check how we want to control the radio
|
|
if radiocontrol == 'direct':
|
|
import rig
|
|
elif radiocontrol == 'rigctl':
|
|
import rigctl as rig
|
|
elif radiocontrol == 'rigctld':
|
|
import rigctld as rig
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
hamlib = rig.radio()
|
|
hamlib.open_rig(devicename=devicename, deviceport=deviceport, hamlib_ptt_type=pttprotocol, serialspeed=serialspeed, pttport=pttport, data_bits=data_bits, stop_bits=stop_bits, handshake=handshake, rigctld_ip=rigctld_ip, rigctld_port = rigctld_port)
|
|
|
|
hamlib_version = rig.hamlib_version
|
|
|
|
hamlib.set_ptt(True)
|
|
pttstate = hamlib.get_ptt()
|
|
|
|
if pttstate:
|
|
structlog.get_logger("structlog").info("[DMN] Hamlib PTT", status = 'SUCCESS')
|
|
response = {'command': 'test_hamlib', 'result': 'SUCCESS'}
|
|
elif not pttstate:
|
|
structlog.get_logger("structlog").warning("[DMN] Hamlib PTT", status = 'NO SUCCESS')
|
|
response = {'command': 'test_hamlib', 'result': 'NOSUCCESS'}
|
|
else:
|
|
structlog.get_logger("structlog").error("[DMN] Hamlib PTT", status = 'FAILED')
|
|
response = {'command': 'test_hamlib', 'result': 'FAILED'}
|
|
|
|
hamlib.set_ptt(False)
|
|
hamlib.close_rig()
|
|
|
|
jsondata = json.dumps(response)
|
|
sock.SOCKET_QUEUE.put(jsondata)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
# --------------------------------------------GET PARAMETER INPUTS
|
|
PARSER = argparse.ArgumentParser(description='Simons TEST TNC')
|
|
PARSER.add_argument('--port', dest="socket_port",default=3001, help="Socket port", type=int)
|
|
|
|
ARGS = PARSER.parse_args()
|
|
static.DAEMONPORT = ARGS.socket_port
|
|
|
|
|
|
try:
|
|
structlog.get_logger("structlog").info("[DMN] Starting TCP/IP socket", port=static.DAEMONPORT)
|
|
# https://stackoverflow.com/a/16641793
|
|
socketserver.TCPServer.allow_reuse_address = True
|
|
cmdserver = sock.ThreadedTCPServer((static.HOST, static.DAEMONPORT), sock.ThreadedTCPRequestHandler)
|
|
server_thread = threading.Thread(target=cmdserver.serve_forever)
|
|
server_thread.daemon = True
|
|
server_thread.start()
|
|
|
|
except Exception as e:
|
|
structlog.get_logger("structlog").error("[DMN] Starting TCP/IP socket failed", port=static.DAEMONPORT, e=e)
|
|
|
|
|
|
daemon = DAEMON()
|
|
while True:
|
|
time.sleep(1) |