mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
Merge pull request #97 from DJ2LS/ls-hamlib-test
hamlib tests and optimization Thanks to @frspin the problems with hamlib ptt seem to be solved. I also added a small test program for doing ctypes experiments with hamlib native api access so the thoughts are not lost. we also keep rigctl.py in the code as a fallback and for further tests and ideas
This commit is contained in:
commit
de6cea866a
127
test/hamlib-test.py
Normal file
127
test/hamlib-test.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import ctypes
|
||||
from ctypes import *
|
||||
import pathlib
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class DEBUGLEVEL(Enum):
|
||||
RIG_DEBUG_NONE = 0
|
||||
RIG_DEBUG_BUG = 1
|
||||
RIG_DEBUG_ERR = 2
|
||||
RIG_DEBUG_WARN = 3
|
||||
RIG_DEBUG_VERBOSE = 4
|
||||
RIG_DEBUG_TRACE = 5
|
||||
RIG_DEBUG_CACHE = 6
|
||||
|
||||
class RETCODE(Enum):
|
||||
RIG_OK = 0
|
||||
RIG_EINVAL = 1
|
||||
RIG_ECONF = 2
|
||||
RIG_ENOMEM = 3
|
||||
RIG_ENIMPL = 4
|
||||
RIG_ETIMEOUT = 5
|
||||
RIG_EIO = 6
|
||||
RIG_EINTERNAL = 7
|
||||
RIG_EPROTO = 8
|
||||
RIG_ERJCTED = 9
|
||||
RIG_ETRUNC = 10
|
||||
RIG_ENAVAIL = 11
|
||||
RIG_ENTARGET = 12
|
||||
RIG_BUSERROR = 13
|
||||
RIG_BUSBUSY = 14
|
||||
RIG_EARG = 15
|
||||
RIG_EVFO = 16
|
||||
RIG_EDOM = 17
|
||||
|
||||
|
||||
|
||||
|
||||
libname = pathlib.Path("../tnc/lib/hamlib/linux/libhamlib.so")
|
||||
hamlib = ctypes.CDLL(libname)
|
||||
|
||||
|
||||
class SERIAL(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("data_bits", ctypes.c_int),
|
||||
("stop_bits", ctypes.c_int),
|
||||
("rate", ctypes.c_int),
|
||||
("parity", ctypes.c_int),
|
||||
("handshake", ctypes.c_void_p),
|
||||
]
|
||||
|
||||
class PARM(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("serial", SERIAL),
|
||||
]
|
||||
|
||||
class TYPE(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("rig", ctypes.c_void_p),
|
||||
]
|
||||
|
||||
class MYPORT(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("pathname", ctypes.c_char),
|
||||
("model", ctypes.c_int),
|
||||
("parm", PARM),
|
||||
("type", TYPE),
|
||||
|
||||
]
|
||||
|
||||
|
||||
hamlib.rig_set_debug(9) #6
|
||||
myrig_model = 3085 #3085 = ICOM 6 = DUMMY
|
||||
|
||||
myport = MYPORT()
|
||||
myport.parm.serial.data_bits = 7
|
||||
myport.parm.serial.stop_bits = 2
|
||||
myport.parm.serial.rate = 9600
|
||||
|
||||
|
||||
|
||||
rig = hamlib.rig_init(myrig_model)
|
||||
|
||||
retcode = hamlib.rig_set_parm(rig, 'stop_bits', 5)
|
||||
print(retcode)
|
||||
|
||||
'''
|
||||
parameter = create_string_buffer(16)
|
||||
retcode = hamlib.rig_get_parm(rig, 0, parameter)
|
||||
print(retcode)
|
||||
print(bytes(parameter))
|
||||
'''
|
||||
|
||||
|
||||
# attempt to access global vars. Maybe we can access structures as well?
|
||||
# https://github.com/Hamlib/Hamlib/blob/f5b229f9dc4b4364d2f40e0b0b415e92c9a371ce/src/rig.c#L95
|
||||
hamlib_version = ctypes.cast(hamlib.hamlib_version, ctypes.POINTER(ctypes.c_char*21))
|
||||
print(hamlib_version.contents.value)
|
||||
|
||||
|
||||
'''
|
||||
retcode = hamlib.rig_has_get_parm(rig, 7)
|
||||
print(retcode)
|
||||
'''
|
||||
|
||||
'''
|
||||
retcode = hamlib.rig_open(rig)
|
||||
print(retcode)
|
||||
|
||||
|
||||
hamlib.rig_close(rig)
|
||||
'''
|
||||
|
||||
|
||||
|
||||
#riginfo = create_string_buffer(1024)
|
||||
#retcode = hamlib.rig_get_rig_info(rig, riginfo, 1024);
|
||||
|
||||
'''
|
||||
char riginfo[1024];
|
||||
retcode = rig_get_rig_info(rig, riginfo, sizeof(riginfo));
|
||||
'''
|
|
@ -20,9 +20,9 @@ import serial.tools.list_ports
|
|||
import static
|
||||
import crcengine
|
||||
import re
|
||||
import rig
|
||||
import logging, structlog, log_handler
|
||||
|
||||
|
||||
log_handler.setup_logging("daemon")
|
||||
# get python version, which is needed later for determining installation path
|
||||
python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1])
|
||||
|
@ -197,7 +197,14 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
|
|||
options.append(stop_bits)
|
||||
options.append('--handshake')
|
||||
options.append(handshake)
|
||||
|
||||
if HAMLIB_USE_RIGCTL:
|
||||
options.append('--rigctl')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# try running tnc from binary, else run from source
|
||||
# this helps running the tnc in a developer environment
|
||||
|
@ -351,11 +358,19 @@ 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)
|
||||
|
||||
PARSER.add_argument('--rigctl', dest="hamlib_use_rigctl",action="store_true", default=False, help="force using of rigctl")
|
||||
|
||||
ARGS = PARSER.parse_args()
|
||||
PORT = ARGS.socket_port
|
||||
|
||||
HAMLIB_USE_RIGCTL = ARGS.hamlib_use_rigctl
|
||||
if HAMLIB_USE_RIGCTL:
|
||||
structlog.get_logger("structlog").warning("using rigctl....")
|
||||
import rigctl as rig
|
||||
else:
|
||||
structlog.get_logger("structlog").warning("using rig.......")
|
||||
import rig
|
||||
# --------------------------------------------START CMD SERVER
|
||||
|
||||
DAEMON_THREAD = threading.Thread(target=start_daemon, name="daemon")
|
||||
DAEMON_THREAD.start()
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +0,0 @@
|
|||
# Hamlib
|
||||
## Linux
|
||||
## Last updated: 02.09.21
|
Binary file not shown.
BIN
tnc/lib/hamlib/linux/libhamlib.so
Executable file
BIN
tnc/lib/hamlib/linux/libhamlib.so
Executable file
Binary file not shown.
|
@ -36,9 +36,8 @@ if __name__ == '__main__':
|
|||
PARSER.add_argument('--data_bits', dest="hamlib_data_bits", default="8", help="Hamlib data bits", type=str)
|
||||
PARSER.add_argument('--stop_bits', dest="hamlib_stop_bits", default="1", help="Hamlib stop bits", type=str)
|
||||
PARSER.add_argument('--handshake', dest="hamlib_handshake", default="None", help="Hamlib handshake", type=str)
|
||||
|
||||
PARSER.add_argument('--rigctl', dest="hamlib_use_rigctl", action="store_true", default=False, help="force using of rigctl")
|
||||
|
||||
|
||||
|
||||
ARGS = PARSER.parse_args()
|
||||
|
||||
|
@ -52,7 +51,9 @@ if __name__ == '__main__':
|
|||
static.HAMLIB_SERIAL_SPEED = ARGS.hamlib_serialspeed
|
||||
static.HAMLIB_DATA_BITS = ARGS.hamlib_data_bits
|
||||
static.HAMLIB_STOP_BITS = ARGS.hamlib_stop_bits
|
||||
static.HAMLIB_HANDSHAKE = ARGS.hamlib_handshake
|
||||
static.HAMLIB_HANDSHAKE = ARGS.hamlib_handshake
|
||||
static.HAMLIB_USE_RIGCTL = ARGS.hamlib_use_rigctl
|
||||
print(ARGS.hamlib_use_rigctl)
|
||||
|
||||
# we need to wait until we got all parameters from argparse first before we can load the other modules
|
||||
import sock
|
||||
|
|
|
@ -22,7 +22,14 @@ import data_handler
|
|||
import re
|
||||
import queue
|
||||
import codec2
|
||||
import rig
|
||||
|
||||
print(static.HAMLIB_USE_RIGCTL)
|
||||
if static.HAMLIB_USE_RIGCTL:
|
||||
structlog.get_logger("structlog").warning("using rigctl....")
|
||||
import rigctl as rig
|
||||
else:
|
||||
structlog.get_logger("structlog").warning("using rig.......")
|
||||
import rig
|
||||
|
||||
# option for testing miniaudio instead of audioop for sample rate conversion
|
||||
#import miniaudio
|
||||
|
|
53
tnc/rig.py
53
tnc/rig.py
|
@ -4,6 +4,7 @@ import sys
|
|||
import re
|
||||
import logging, structlog, log_handler
|
||||
import atexit
|
||||
import subprocess
|
||||
|
||||
|
||||
# try importing hamlib
|
||||
|
@ -29,9 +30,23 @@ try:
|
|||
else:
|
||||
structlog.get_logger("structlog").warning("[TNC] Hamlib outdated", found=hamlib_version, recommend=min_hamlib_version)
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").critical("[TNC] Hamlib not found", error=e)
|
||||
|
||||
|
||||
structlog.get_logger("structlog").warning("[TNC] Python Hamlib binding not found", error=e)
|
||||
try:
|
||||
structlog.get_logger("structlog").warning("[TNC] Trying to open rigctl", error=e)
|
||||
rigctl = subprocess.Popen("rigctl -V",shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
hamlib_version = rigctl.stdout.readline()
|
||||
hamlib_version = hamlib_version.split(' ')
|
||||
print(hamlib_version[0])
|
||||
print(hamlib_version[1])
|
||||
print(hamlib_version[2])
|
||||
if hamlib_version[1] == 'Hamlib':
|
||||
rigctl = True
|
||||
print(hamlib_version)
|
||||
else:
|
||||
rigctl = False
|
||||
raise Exception
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").critical("[TNC] HAMLIB NOT INSTALLED", error=e)
|
||||
|
||||
class radio:
|
||||
def __init__(self):
|
||||
|
@ -50,13 +65,13 @@ class radio:
|
|||
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake):
|
||||
|
||||
self.devicename = devicename
|
||||
self.deviceport = deviceport
|
||||
self.deviceport = str(deviceport)
|
||||
self.serialspeed = str(serialspeed) # we need to ensure this is a str, otherwise set_conf functions are crashing
|
||||
self.hamlib_ptt_type = hamlib_ptt_type
|
||||
self.pttport = pttport
|
||||
self.data_bits = data_bits
|
||||
self.stop_bits = stop_bits
|
||||
self.handshake = handshake
|
||||
self.hamlib_ptt_type = str(hamlib_ptt_type)
|
||||
self.pttport = str(pttport)
|
||||
self.data_bits = str(data_bits)
|
||||
self.stop_bits = str(stop_bits)
|
||||
self.handshake = str(handshake)
|
||||
|
||||
|
||||
# try to init hamlib
|
||||
|
@ -66,6 +81,7 @@ class radio:
|
|||
# get devicenumber by looking for deviceobject in Hamlib module
|
||||
try:
|
||||
self.devicenumber = int(getattr(Hamlib, self.devicename))
|
||||
print(self.devicenumber)
|
||||
except:
|
||||
structlog.get_logger("structlog").error("[DMN] Hamlib: rig not supported...")
|
||||
self.devicenumber = 0
|
||||
|
@ -80,6 +96,16 @@ class radio:
|
|||
self.my_rig.set_conf("data_bits", self.data_bits)
|
||||
self.my_rig.set_conf("ptt_pathname", self.pttport)
|
||||
|
||||
|
||||
print(self.my_rig.get_conf("rig_pathname"))
|
||||
print(self.my_rig.get_conf("retry"))
|
||||
print(self.my_rig.get_conf("serial_speed"))
|
||||
print(self.my_rig.get_conf("serial_handshake"))
|
||||
print(self.my_rig.get_conf("stop_bits"))
|
||||
print(self.my_rig.get_conf("data_bits"))
|
||||
print(self.my_rig.get_conf("ptt_pathname"))
|
||||
|
||||
|
||||
|
||||
if self.hamlib_ptt_type == 'RIG':
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG
|
||||
|
@ -159,17 +185,18 @@ class radio:
|
|||
(hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
return bandwith
|
||||
|
||||
def set_mode(self, mode):
|
||||
return 0
|
||||
# not needed yet beacuse of some possible problems
|
||||
#def set_mode(self, mode):
|
||||
# return 0
|
||||
|
||||
def get_ptt(self):
|
||||
return self.my_rig.get_ptt()
|
||||
|
||||
def set_ptt(self, state):
|
||||
if state:
|
||||
self.my_rig.set_ptt(self.hamlib_ptt_type, 1)
|
||||
self.my_rig.set_ptt(Hamlib.RIG_VFO_CURR, 1)
|
||||
else:
|
||||
self.my_rig.set_ptt(self.hamlib_ptt_type, 0)
|
||||
self.my_rig.set_ptt(Hamlib.RIG_VFO_CURR, 0)
|
||||
return state
|
||||
|
||||
def close_rig(self):
|
||||
|
|
109
tnc/rigctl.py
Normal file
109
tnc/rigctl.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python3
|
||||
# Franco Spinelli, IW2DHW
|
||||
#
|
||||
# versione mia di rig.py per gestire Ft897D tramite rigctl e senza
|
||||
# fare alcun riferimento alla configurazione
|
||||
#
|
||||
# e' una pezza clamorosa ma serve per poter provare on-air il modem
|
||||
#
|
||||
import subprocess
|
||||
#
|
||||
import sys
|
||||
import re
|
||||
import logging, structlog, log_handler
|
||||
import atexit
|
||||
import time
|
||||
# for rig_model -> rig_number only
|
||||
|
||||
|
||||
class radio:
|
||||
def __init__(self):
|
||||
|
||||
self.devicename = ''
|
||||
self.devicenumber = ''
|
||||
self.deviceport = ''
|
||||
self.serialspeed = ''
|
||||
self.hamlib_ptt_type = ''
|
||||
self.my_rig = ''
|
||||
self.pttport = ''
|
||||
self.data_bits = ''
|
||||
self.stop_bits = ''
|
||||
self.handshake = ''
|
||||
|
||||
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake):
|
||||
|
||||
self.devicename = devicename
|
||||
self.deviceport = deviceport
|
||||
self.serialspeed = str(serialspeed) # we need to ensure this is a str, otherwise set_conf functions are crashing
|
||||
self.hamlib_ptt_type = hamlib_ptt_type
|
||||
self.pttport = pttport
|
||||
self.data_bits = data_bits
|
||||
self.stop_bits = stop_bits
|
||||
self.handshake = handshake
|
||||
|
||||
# get devicenumber by looking for deviceobject in Hamlib module
|
||||
try:
|
||||
import Hamlib
|
||||
self.devicenumber = int(getattr(Hamlib, self.devicename))
|
||||
except:
|
||||
if int(self.devicename):
|
||||
self.devicenumber = int(self.devicename)
|
||||
else:
|
||||
self.devicenumber = 6 #dummy
|
||||
structlog.get_logger("structlog").warning("[TNC] RADIO NOT FOUND USING DUMMY!", error=e)
|
||||
|
||||
|
||||
print(self.devicenumber, self.deviceport, self.serialspeed)
|
||||
self.cmd = 'rigctl -m %d -r %s -s %d ' % (int(self.devicenumber), self.deviceport, int(self.serialspeed))
|
||||
|
||||
# eseguo semplicemente rigctl con il solo comando T 1 o T 0 per
|
||||
# il set e t per il get
|
||||
|
||||
# set ptt to false if ptt is stuck for some reason
|
||||
self.set_ptt(False)
|
||||
return True
|
||||
|
||||
def get_frequency(self):
|
||||
cmd = self.cmd + ' f'
|
||||
sw_proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
time.sleep(0.5)
|
||||
freq = sw_proc.communicate()[0]
|
||||
#print('get_frequency', freq, sw_proc.communicate())
|
||||
return int(freq)
|
||||
|
||||
def get_mode(self):
|
||||
#(hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
#return Hamlib.rig_strrmode(hamlib_mode)
|
||||
return 'PKTUSB'
|
||||
|
||||
def get_bandwith(self):
|
||||
#(hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
bandwith = 2700
|
||||
return bandwith
|
||||
|
||||
def set_mode(self, mode):
|
||||
# non usata
|
||||
return 0
|
||||
|
||||
def get_ptt(self):
|
||||
cmd = self.cmd + ' t'
|
||||
sw_proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
time.sleep(0.5)
|
||||
status = sw_proc.communicate()[0]
|
||||
return status
|
||||
|
||||
def set_ptt(self, state):
|
||||
cmd = self.cmd + ' T '
|
||||
print('set_ptt', state)
|
||||
if state:
|
||||
cmd = cmd + '1'
|
||||
else:
|
||||
cmd = cmd + '0'
|
||||
print('set_ptt', cmd)
|
||||
|
||||
sw_proc = subprocess.Popen(cmd, shell=True, text=True)
|
||||
return state
|
||||
|
||||
def close_rig(self):
|
||||
#self.my_rig.close()
|
||||
return
|
|
@ -338,8 +338,7 @@ def start_cmd_socket():
|
|||
structlog.get_logger("structlog").info("[TNC] Starting TCP/IP socket", port=static.PORT)
|
||||
# https://stackoverflow.com/a/16641793
|
||||
socketserver.TCPServer.allow_reuse_address = True
|
||||
cmdserver = ThreadedTCPServer(
|
||||
(static.HOST, static.PORT), ThreadedTCPRequestHandler)
|
||||
cmdserver = ThreadedTCPServer((static.HOST, static.PORT), ThreadedTCPRequestHandler)
|
||||
server_thread = threading.Thread(target=cmdserver.serve_forever)
|
||||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
|
|
|
@ -44,6 +44,7 @@ HAMLIB_PTT_PORT = '/dev/ttyUSB0'
|
|||
HAMLIB_STOP_BITS = '1'
|
||||
HAMLIB_DATA_BITS = '8'
|
||||
HAMLIB_HANDSHAKE = 'None'
|
||||
HAMLIB_USE_RIGCTL = False
|
||||
|
||||
HAMLIB_FREQUENCY = 0
|
||||
HAMLIB_MODE = ''
|
||||
|
|
Loading…
Reference in a new issue