PyFT8 3.0.2__tar.gz → 3.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyft8-3.0.2 → pyft8-3.1.0}/PKG-INFO +1 -1
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/databases.py +12 -7
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/pyft8.py +9 -4
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/receiver.py +3 -3
- pyft8-3.1.0/PyFT8/rigctrl.py +103 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8.egg-info/PKG-INFO +1 -1
- {pyft8-3.0.2 → pyft8-3.1.0}/pyproject.toml +1 -1
- pyft8-3.0.2/PyFT8/rigctrl.py +0 -43
- {pyft8-3.0.2 → pyft8-3.1.0}/LICENSE +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/MANIFEST.in +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/__init__.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/gui.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/pskreporter.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/time_utils.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8/transmitter.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8.egg-info/SOURCES.txt +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8.egg-info/dependency_links.txt +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8.egg-info/entry_points.txt +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8.egg-info/requires.txt +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/PyFT8.egg-info/top_level.txt +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/README.md +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/setup.cfg +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/dev/CQ AAAA.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/dev/osd.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/dev/test_generate_wav.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/dev/test_loopback_performance.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/dev/view_worked_before.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/plot_baseline.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/spare.py +0 -0
- {pyft8-3.0.2 → pyft8-3.1.0}/tests/test_batch_and_live.py +0 -0
|
@@ -71,12 +71,17 @@ class DiskDict:
|
|
|
71
71
|
pass
|
|
72
72
|
|
|
73
73
|
def save(self):
|
|
74
|
-
|
|
75
|
-
with
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
if self.data != {}:
|
|
75
|
+
with self.lock:
|
|
76
|
+
with open(f"{self.file}_tmp", "w") as f:
|
|
77
|
+
try:
|
|
78
|
+
json.dump(self.data, f)
|
|
79
|
+
except:
|
|
80
|
+
return
|
|
81
|
+
try:
|
|
82
|
+
os.replace(f"{self.file}_tmp", self.file)
|
|
83
|
+
except:
|
|
84
|
+
return
|
|
80
85
|
|
|
81
86
|
class History:
|
|
82
87
|
def __init__(self, config_folder, my_call, home_square, pskr_refresh_mins, parse_all_file):
|
|
@@ -185,7 +190,7 @@ class History:
|
|
|
185
190
|
self._update_new_alert(band, call, historic_data, new_alert_data)
|
|
186
191
|
historic_data.setdefault(band, {})
|
|
187
192
|
if call in historic_data[band]:
|
|
188
|
-
if t < historic_data[band][call]['t']:
|
|
193
|
+
if int(t) < int(historic_data[band][call]['t']):
|
|
189
194
|
return
|
|
190
195
|
historic_data[band][call] = {'t': int(t),'rp':int(rp)}
|
|
191
196
|
|
|
@@ -9,10 +9,10 @@ from PyFT8.pskreporter import PSKR_upload
|
|
|
9
9
|
from PyFT8.gui import Gui
|
|
10
10
|
from PyFT8.transmitter import AudioOut
|
|
11
11
|
from PyFT8.time_utils import global_time_utils
|
|
12
|
-
from PyFT8.rigctrl import Rig_hamlib
|
|
12
|
+
from PyFT8.rigctrl import Rig_hamlib, Rig_CAT
|
|
13
13
|
from PyFT8.databases import History, ADIF
|
|
14
14
|
|
|
15
|
-
VER = '3.0
|
|
15
|
+
VER = '3.1.0'
|
|
16
16
|
|
|
17
17
|
MAX_TX_START_SECONDS = 2.5
|
|
18
18
|
HEARING_PANEL_LIFE_MINS = 20
|
|
@@ -315,8 +315,7 @@ def cli():
|
|
|
315
315
|
import time, sys
|
|
316
316
|
parser = argparse.ArgumentParser(prog='PyFT8rx', description = 'Command Line FT8 decoder')
|
|
317
317
|
parser.add_argument('-c', '--config_folder', help = 'Location of config folder e.g. C:/Users/drala/Documents/Projects/GitHub/G1OJS/PyFT8_cfg', default = './')
|
|
318
|
-
parser.add_argument('-i', '--inputcard_keywords', help = 'Comma-separated keywords to identify the input sound device')
|
|
319
|
-
#parser.add_argument('-v','--verbose', action='store_true', help = 'Verbose: include debugging output')
|
|
318
|
+
parser.add_argument('-i', '--inputcard_keywords', help = 'Comma-separated keywords to identify the input sound device')
|
|
320
319
|
parser.add_argument('-o','--outputcard_keywords', help = 'Comma-separated keywords to identify the output sound device')
|
|
321
320
|
parser.add_argument('-n','--no_gui', action='store_true', help = "Don't create a gui")
|
|
322
321
|
parser.add_argument('-m','--transmit_message', nargs='?', help = 'Transmit a message')
|
|
@@ -348,6 +347,12 @@ def cli():
|
|
|
348
347
|
if config.has_section('hamlib_rig'):
|
|
349
348
|
console_print("Connecting to rig via Hamlib")
|
|
350
349
|
rig = Rig_hamlib(config)
|
|
350
|
+
else:
|
|
351
|
+
console_print("Connecting to rig via CAT")
|
|
352
|
+
rig = Rig_CAT(config)
|
|
353
|
+
|
|
354
|
+
if config.has_section('launch'):
|
|
355
|
+
os.system(config['launch']['app'])
|
|
351
356
|
|
|
352
357
|
if args.outputcard_keywords:
|
|
353
358
|
outputcard_keywords = args.outputcard_keywords.replace(' ','').split(',')
|
|
@@ -45,10 +45,10 @@ def unpack(bits):
|
|
|
45
45
|
i3, bits74 = get_bitfields(bits,[3])
|
|
46
46
|
if i3 == 0:
|
|
47
47
|
n3, bits71 = get_bitfields(bits74,[3])
|
|
48
|
-
if n3
|
|
49
|
-
return ('Free text','not','implemented')
|
|
48
|
+
if n3 <= 4:
|
|
49
|
+
return (['Free text', 'DXpedition','Field Day', 'Field Day', 'Telemetry'][n3],'not','implemented')
|
|
50
50
|
else:
|
|
51
|
-
return (
|
|
51
|
+
return ('Unknown mode','not','implemented')
|
|
52
52
|
elif i3 == 1 or i3 == 2: # 1 = Std Msg incl /R 2 = 'EU VHF' = Std Msg incl /P
|
|
53
53
|
return unpack_std(bits74, i3)
|
|
54
54
|
elif i3 == 3:
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import serial, time, socket, subprocess, threading, psutil
|
|
2
|
+
|
|
3
|
+
class Rig_CAT:
|
|
4
|
+
def __init__(self, config, verbose = False):
|
|
5
|
+
self.serial_port = False
|
|
6
|
+
self.port = config['rig']['port']
|
|
7
|
+
self.baud_rate = config['rig']['baud_rate']
|
|
8
|
+
self.ptt_on_cmd = self.parse_configstr(config['rig']['ptt_on_command']) if config['rig']['ptt_on_command']else None
|
|
9
|
+
self.ptt_off_cmd = self.parse_configstr(config['rig']['ptt_off_command']) if config['rig']['ptt_off_command'] else None
|
|
10
|
+
self.set_freq_cmd = self.parse_configstr(config['rig']['set_freq_command']) if config['rig']['set_freq_command'] else None
|
|
11
|
+
self.set_freq_value = config['rig']['set_freq_value'] if config['rig']['set_freq_value'] else None
|
|
12
|
+
self.verbose = verbose
|
|
13
|
+
|
|
14
|
+
def parse_configstr(self, configstr):
|
|
15
|
+
if "." in configstr:
|
|
16
|
+
hexstr = configstr.replace(".", "")
|
|
17
|
+
return bytearray.fromhex(hexstr)
|
|
18
|
+
else:
|
|
19
|
+
return bytearray(configstr.encode())
|
|
20
|
+
|
|
21
|
+
def vprint(self, text):
|
|
22
|
+
if self.verbose:
|
|
23
|
+
print(text)
|
|
24
|
+
|
|
25
|
+
def _sendCAT(self, msg):
|
|
26
|
+
try:
|
|
27
|
+
self.serial_port = serial.Serial(port = self.port, baudrate = self.baud_rate, timeout = 0.1)
|
|
28
|
+
except Exception as e:
|
|
29
|
+
print(f"[CAT] couldn't open {self.port}: {e}")
|
|
30
|
+
if (self.serial_port):
|
|
31
|
+
self.serial_port.reset_input_buffer()
|
|
32
|
+
self.vprint(f"[CAT] send {msg.hex(' ')}")
|
|
33
|
+
try:
|
|
34
|
+
self.serial_port.write(msg)
|
|
35
|
+
time.sleep(0.05)
|
|
36
|
+
self.serial_port.close()
|
|
37
|
+
except Exception as e:
|
|
38
|
+
print(f"[CAT] couldn't send CAT command {msg} on {self.port}: {e}")
|
|
39
|
+
|
|
40
|
+
def set_freq_Hz(self, freqHz):
|
|
41
|
+
if self.set_freq_cmd and self.set_freq_value:
|
|
42
|
+
self.vprint(f"[CAT] SET frequency to {freqHz} Hz")
|
|
43
|
+
start, length, fmt, mult, offset = self.set_freq_value.split("|")
|
|
44
|
+
start, length, mult, offset = int(start), int(length), int(mult), int(offset)
|
|
45
|
+
fVal = freqHz * mult + offset
|
|
46
|
+
nDigits = length if fmt == "text" else 2*length
|
|
47
|
+
s = f"{fVal:0{nDigits}d}"
|
|
48
|
+
if fmt=='text':
|
|
49
|
+
fBytes = s.encode()
|
|
50
|
+
else:
|
|
51
|
+
pairs = [(int(s[i]) << 4) | int(s[i+1]) for i in range(0, len(s), 2)]
|
|
52
|
+
if fmt == "vfBcdLU":
|
|
53
|
+
fBytes = bytes(pairs[::-1])
|
|
54
|
+
else:
|
|
55
|
+
fBytes = bytes(pairs)
|
|
56
|
+
cmd = bytearray(self.set_freq_cmd)
|
|
57
|
+
cmd[start:start+length] = fBytes
|
|
58
|
+
if fmt.startswith("vfBcd"): # CI-V
|
|
59
|
+
cmd = b'\x00' + cmd
|
|
60
|
+
self._sendCAT(cmd)
|
|
61
|
+
|
|
62
|
+
def ptt_on(self):
|
|
63
|
+
if self.ptt_on_cmd:
|
|
64
|
+
self.vprint(f"[CAT] PTT On")
|
|
65
|
+
self._sendCAT(self.ptt_on_cmd)
|
|
66
|
+
|
|
67
|
+
def ptt_off(self):
|
|
68
|
+
if self.ptt_off_cmd:
|
|
69
|
+
self.vprint(f"[CAT] PTT Off")
|
|
70
|
+
self._sendCAT(self.ptt_off_cmd)
|
|
71
|
+
|
|
72
|
+
class Rig_hamlib:
|
|
73
|
+
def __init__(self, config):
|
|
74
|
+
com = config['hamlib_rig']['port']
|
|
75
|
+
s = config['hamlib_rig']['baud_rate']
|
|
76
|
+
rigctld = config['hamlib_rig']['rigctld']
|
|
77
|
+
rig = config['hamlib_rig']['model']
|
|
78
|
+
host, port ="localhost", 4532
|
|
79
|
+
if not any(['rigctld' in i.name() for i in psutil.process_iter()]):
|
|
80
|
+
cmd = f"{rigctld} -m {rig} -r {com} -s {s}"
|
|
81
|
+
threading.Thread(target = subprocess.run, args = (cmd,)).start()
|
|
82
|
+
time.sleep(0.5)
|
|
83
|
+
self.sock = socket.create_connection((host, port))
|
|
84
|
+
self.set_mode("PKTUSB")
|
|
85
|
+
|
|
86
|
+
def cmd(self, command):
|
|
87
|
+
if self.sock:
|
|
88
|
+
self.sock.sendall((command + "\n").encode())
|
|
89
|
+
return self.sock.recv(1024).decode()
|
|
90
|
+
|
|
91
|
+
def set_mode(self, mode):
|
|
92
|
+
self.cmd(f"M {mode} 0")
|
|
93
|
+
|
|
94
|
+
def set_freq_Hz(self, hz):
|
|
95
|
+
self.cmd(f"F {hz}")
|
|
96
|
+
|
|
97
|
+
def ptt_on(self):
|
|
98
|
+
self.cmd(f"T 1")
|
|
99
|
+
|
|
100
|
+
def ptt_off(self):
|
|
101
|
+
self.cmd(f"T 0")
|
|
102
|
+
|
|
103
|
+
|
pyft8-3.0.2/PyFT8/rigctrl.py
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import time, socket, subprocess, threading
|
|
2
|
-
|
|
3
|
-
class Rig_hamlib:
|
|
4
|
-
def __init__(self, config):
|
|
5
|
-
com = config['hamlib_rig']['port']
|
|
6
|
-
s = config['hamlib_rig']['baud_rate']
|
|
7
|
-
rigctld = config['hamlib_rig']['rigctld']
|
|
8
|
-
rig = config['hamlib_rig']['model']
|
|
9
|
-
host, port ="localhost", 4532
|
|
10
|
-
cmd = f"{rigctld} -m {rig} -r {com} -s {s}"
|
|
11
|
-
self.sock = None
|
|
12
|
-
if not self.create_socket(host, port):
|
|
13
|
-
threading.Thread(target = subprocess.run, args = (cmd,)).start()
|
|
14
|
-
time.sleep(0.5)
|
|
15
|
-
if not self.create_socket(host, port):
|
|
16
|
-
print(f"Couldn't create socket for hamlib on {host}:{port}")
|
|
17
|
-
self.set_mode("PKTUSB")
|
|
18
|
-
|
|
19
|
-
def create_socket(self, host, port):
|
|
20
|
-
try:
|
|
21
|
-
self.sock = socket.create_connection((host, port))
|
|
22
|
-
except:
|
|
23
|
-
return False
|
|
24
|
-
return True
|
|
25
|
-
|
|
26
|
-
def cmd(self, command):
|
|
27
|
-
if self.sock:
|
|
28
|
-
self.sock.sendall((command + "\n").encode())
|
|
29
|
-
return self.sock.recv(1024).decode()
|
|
30
|
-
|
|
31
|
-
def set_mode(self, mode):
|
|
32
|
-
self.cmd(f"M {mode} 0")
|
|
33
|
-
|
|
34
|
-
def set_freq_Hz(self, hz):
|
|
35
|
-
self.cmd(f"F {hz}")
|
|
36
|
-
|
|
37
|
-
def ptt_on(self):
|
|
38
|
-
self.cmd(f"T 1")
|
|
39
|
-
|
|
40
|
-
def ptt_off(self):
|
|
41
|
-
self.cmd(f"T 0")
|
|
42
|
-
|
|
43
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|