not1mm 24.4.4.1__py3-none-any.whl → 24.4.9__py3-none-any.whl
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.
- not1mm/__main__.py +33 -3
- not1mm/checkwindow.py +1 -1
- not1mm/lib/ft8_watcher.py +132 -0
- not1mm/lib/version.py +1 -1
- {not1mm-24.4.4.1.dist-info → not1mm-24.4.9.dist-info}/METADATA +3 -1
- {not1mm-24.4.4.1.dist-info → not1mm-24.4.9.dist-info}/RECORD +10 -9
- {not1mm-24.4.4.1.dist-info → not1mm-24.4.9.dist-info}/LICENSE +0 -0
- {not1mm-24.4.4.1.dist-info → not1mm-24.4.9.dist-info}/WHEEL +0 -0
- {not1mm-24.4.4.1.dist-info → not1mm-24.4.9.dist-info}/entry_points.txt +0 -0
- {not1mm-24.4.4.1.dist-info → not1mm-24.4.9.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -62,6 +62,7 @@ from not1mm.lib.select_contest import SelectContest
|
|
62
62
|
from not1mm.lib.settings import Settings
|
63
63
|
from not1mm.lib.version import __version__
|
64
64
|
from not1mm.lib.versiontest import VersionTest
|
65
|
+
from not1mm.lib.ft8_watcher import FT8Watcher
|
65
66
|
|
66
67
|
import not1mm.fsutils as fsutils
|
67
68
|
from not1mm.logwindow import LogWindow
|
@@ -199,6 +200,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
199
200
|
self.leftdot.hide()
|
200
201
|
self.rightdot.hide()
|
201
202
|
self.n1mm = N1MM()
|
203
|
+
self.ft8 = FT8Watcher()
|
204
|
+
self.ft8.set_callback(self.ft8_result)
|
202
205
|
self.mscp = SCP(fsutils.APP_DATA_PATH)
|
203
206
|
self.next_field = self.other_2
|
204
207
|
self.dupe_indicator.hide()
|
@@ -461,7 +464,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
461
464
|
}
|
462
465
|
|
463
466
|
self.setWindowIcon(
|
464
|
-
QtGui.QIcon(str(fsutils.APP_DATA_PATH / "k6gte.not1mm-
|
467
|
+
QtGui.QIcon(str(fsutils.APP_DATA_PATH / "k6gte.not1mm-32.png"))
|
465
468
|
)
|
466
469
|
self.readpreferences()
|
467
470
|
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
@@ -525,6 +528,33 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
525
528
|
"You can udate to the current version by using:\npip install -U not1mm"
|
526
529
|
)
|
527
530
|
|
531
|
+
def ft8_result(self, result: dict):
|
532
|
+
"""
|
533
|
+
Callback for ft8 watcher
|
534
|
+
|
535
|
+
{
|
536
|
+
'CALL': 'KE0OG',
|
537
|
+
'GRIDSQUARE': 'DM10AT',
|
538
|
+
'MODE': 'FT8',
|
539
|
+
'RST_SENT': '',
|
540
|
+
'RST_RCVD': '',
|
541
|
+
'QSO_DATE': '20210329',
|
542
|
+
'TIME_ON': '183213',
|
543
|
+
'QSO_DATE_OFF': '20210329',
|
544
|
+
'TIME_OFF': '183213',
|
545
|
+
'BAND': '20M',
|
546
|
+
'FREQ': '14.074754',
|
547
|
+
'STATION_CALLSIGN': 'K6GTE',
|
548
|
+
'MY_GRIDSQUARE': 'DM13AT',
|
549
|
+
'CONTEST_ID': 'ARRL-FIELD-DAY',
|
550
|
+
'SRX_STRING': '1D UT',
|
551
|
+
'CLASS': '1D',
|
552
|
+
'ARRL_SECT': 'UT'
|
553
|
+
}
|
554
|
+
|
555
|
+
"""
|
556
|
+
print(f"{result=}")
|
557
|
+
|
528
558
|
def setDarkMode(self, dark):
|
529
559
|
"""testing"""
|
530
560
|
|
@@ -3422,8 +3452,8 @@ logging.basicConfig(
|
|
3422
3452
|
logging.StreamHandler(),
|
3423
3453
|
],
|
3424
3454
|
)
|
3425
|
-
logging.getLogger("
|
3426
|
-
logging.getLogger("
|
3455
|
+
logging.getLogger("PyQt6.uic.uiparser").setLevel("INFO")
|
3456
|
+
logging.getLogger("PyQt6.uic.properties").setLevel("INFO")
|
3427
3457
|
app = QtWidgets.QApplication(sys.argv)
|
3428
3458
|
families = load_fonts_from_dir(os.fspath(fsutils.APP_DATA_PATH))
|
3429
3459
|
logger.info(f"font families {families}")
|
not1mm/checkwindow.py
CHANGED
@@ -62,7 +62,7 @@ class CheckWindow(QDockWidget):
|
|
62
62
|
self.multicast_interface = Multicast(
|
63
63
|
self.pref.get("multicast_group", "239.1.1.1"),
|
64
64
|
self.pref.get("multicast_port", 2239),
|
65
|
-
self.pref.get("interface_ip", "0
|
65
|
+
self.pref.get("interface_ip", "0.0.0.0"),
|
66
66
|
)
|
67
67
|
self.multicast_interface.ready_read_connect(self.watch_udp)
|
68
68
|
|
@@ -0,0 +1,132 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
WSJT-x UDP Packet Watcher
|
4
|
+
Email: michael.bridak@gmail.com
|
5
|
+
https://github.com/mbridak/not1mm
|
6
|
+
GPL V3
|
7
|
+
"""
|
8
|
+
|
9
|
+
from PyQt6 import QtNetwork
|
10
|
+
|
11
|
+
# import struct
|
12
|
+
|
13
|
+
|
14
|
+
class FT8Watcher:
|
15
|
+
"""Main Window"""
|
16
|
+
|
17
|
+
datadict = {}
|
18
|
+
|
19
|
+
def __init__(self, *args, **kwargs):
|
20
|
+
"""Initialize"""
|
21
|
+
super().__init__(*args, **kwargs)
|
22
|
+
self.callback = None
|
23
|
+
self.udp_socket = QtNetwork.QUdpSocket()
|
24
|
+
self.udp_socket.bind(QtNetwork.QHostAddress.SpecialAddress.LocalHost, 2237)
|
25
|
+
self.udp_socket.readyRead.connect(self.on_udp_socket_ready_read)
|
26
|
+
|
27
|
+
def set_callback(self, callback):
|
28
|
+
"""Set callback"""
|
29
|
+
self.callback = callback
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def getint(bytestring):
|
33
|
+
"""
|
34
|
+
Returns an int from a bigendian signed 4 byte string
|
35
|
+
"""
|
36
|
+
return int.from_bytes(bytestring, byteorder="big", signed=True)
|
37
|
+
|
38
|
+
@staticmethod
|
39
|
+
def getuint(bytestring):
|
40
|
+
"""
|
41
|
+
Returns an int from a bigendian unsigned 4 byte string
|
42
|
+
"""
|
43
|
+
return int.from_bytes(bytestring, byteorder="big", signed=False)
|
44
|
+
|
45
|
+
@staticmethod
|
46
|
+
def getbool(bytestring):
|
47
|
+
"""
|
48
|
+
Returns a bool from a 1 byte string
|
49
|
+
"""
|
50
|
+
return bool.from_bytes(bytestring, byteorder="big", signed=False)
|
51
|
+
|
52
|
+
def getvalue(self, item):
|
53
|
+
"""I don't remember what this does."""
|
54
|
+
if item in self.datadict:
|
55
|
+
return self.datadict[item]
|
56
|
+
return "NOT_FOUND"
|
57
|
+
|
58
|
+
def on_udp_socket_ready_read(self):
|
59
|
+
"""
|
60
|
+
This will process incomming UDP log packets from WSJT-X.
|
61
|
+
I Hope...
|
62
|
+
"""
|
63
|
+
self.datadict = {}
|
64
|
+
datagram, sender_host, sender_port_number = self.udp_socket.readDatagram(
|
65
|
+
self.udp_socket.pendingDatagramSize()
|
66
|
+
)
|
67
|
+
# print("%s %s %s", sender_host, sender_port_number, datagram)
|
68
|
+
|
69
|
+
if datagram[0:4] != b"\xad\xbc\xcb\xda":
|
70
|
+
return # bail if no wsjt-x magic number
|
71
|
+
version = self.getuint(datagram[4:8])
|
72
|
+
packettype = self.getuint(datagram[8:12])
|
73
|
+
uniquesize = self.getint(datagram[12:16])
|
74
|
+
unique = datagram[16 : 16 + uniquesize].decode()
|
75
|
+
payload = datagram[16 + uniquesize :]
|
76
|
+
|
77
|
+
if packettype == 0: # Heartbeat
|
78
|
+
hbmaxschema = self.getuint(payload[0:4])
|
79
|
+
hbversion_len = self.getint(payload[4:8])
|
80
|
+
hbversion = payload[8 : 8 + hbversion_len].decode()
|
81
|
+
print(
|
82
|
+
f"heartbeat: sv:{version} p:{packettype} "
|
83
|
+
f"u:{unique}: ms:{hbmaxschema} av:{hbversion}"
|
84
|
+
)
|
85
|
+
return
|
86
|
+
|
87
|
+
if packettype == 1: # Status
|
88
|
+
...
|
89
|
+
# [dialfreq] = struct.unpack(">Q", payload[0:8])
|
90
|
+
# modelen = self.getint(payload[8:12])
|
91
|
+
# mode = payload[12 : 12 + modelen].decode()
|
92
|
+
# payload = payload[12 + modelen :]
|
93
|
+
# dxcalllen = self.getint(payload[0:4])
|
94
|
+
# dxcall = payload[4 : 4 + dxcalllen].decode()
|
95
|
+
# print(
|
96
|
+
# "Status: sv:%s p:%s u:%s df:%s m:%s dxc:%s",
|
97
|
+
# version,
|
98
|
+
# packettype,
|
99
|
+
# unique,
|
100
|
+
# dialfreq,
|
101
|
+
# mode,
|
102
|
+
# dxcall,
|
103
|
+
# )
|
104
|
+
|
105
|
+
# if f"{dxcall}{self.band}{self.mode}" in self.dupdict:
|
106
|
+
# self.ft8dupe = f"{dxcall} {self.band}M {self.mode} FT8 Dupe!"
|
107
|
+
return
|
108
|
+
|
109
|
+
if packettype == 2: # Decode commented out because we really don't care
|
110
|
+
return
|
111
|
+
|
112
|
+
if packettype != 12:
|
113
|
+
return # bail if not logged ADIF
|
114
|
+
# if log packet it will contain this nugget.
|
115
|
+
gotcall = datagram.find(b"<call:")
|
116
|
+
if gotcall != -1:
|
117
|
+
datagram = datagram[gotcall:] # strip everything else
|
118
|
+
else:
|
119
|
+
return # Otherwise we don't want to bother with this packet
|
120
|
+
|
121
|
+
data = datagram.decode()
|
122
|
+
splitdata = data.upper().split("<")
|
123
|
+
|
124
|
+
for data in splitdata:
|
125
|
+
if data:
|
126
|
+
tag = data.split(":")
|
127
|
+
if tag == ["EOR>"]:
|
128
|
+
break
|
129
|
+
self.datadict[tag[0]] = tag[1].split(">")[1].strip()
|
130
|
+
|
131
|
+
if self.callback:
|
132
|
+
self.callback(self.datadict)
|
not1mm/lib/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version: 24.4.
|
3
|
+
Version: 24.4.9
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
Project-URL: Homepage, https://github.com/mbridak/not1mm
|
@@ -177,6 +177,8 @@ I wish to thank those who've contributed to the project.
|
|
177
177
|
|
178
178
|
## Recent Changes
|
179
179
|
|
180
|
+
- [24-4-9] Fixed Checkwindow not showing calls from logged contacts.
|
181
|
+
- [24-4-7] Added FT8Watcher class to prep for FT8 support.
|
180
182
|
- [24-4-4-1] Made docking widgets open state persistent.
|
181
183
|
- [24-4-4] Added per-contest echange hint when adding new contest.
|
182
184
|
- [24-4-2] Migrated to PyQt6. I'm sure there are broken things.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=PSN9XggwaLiIcjJrh0akGib7kGAARzK2pytiQjdPNbg,122807
|
3
3
|
not1mm/bandmap.py,sha256=-wHbUmj-zqefyFO_ydLECwTtWcs37tSkA7Xm2zOVcLA,34318
|
4
|
-
not1mm/checkwindow.py,sha256=
|
4
|
+
not1mm/checkwindow.py,sha256=Ba2mSupOso3vGh6pj0xykxSxRT3TdqHus_ODRlkV8ok,10465
|
5
5
|
not1mm/fsutils.py,sha256=Li8Tq9K7c_q7onOHOQ7u1dOOFfhIIz5Aj2LKuQtGOO4,1652
|
6
6
|
not1mm/logwindow.py,sha256=H6FbKowq5ekEhALRPiRugZk_Rv1mwtMF5VT_OBZ63Oo,44900
|
7
7
|
not1mm/vfo.py,sha256=HIr73gob-JLaJqn0TpTYxWApwKR1YpmA43M8QyTnYik,12467
|
@@ -95,6 +95,7 @@ not1mm/lib/edit_contact.py,sha256=Ki9bGPpqyQQBB1cU8VIBDCal3lbXeQ6qxhzklmhE2_w,35
|
|
95
95
|
not1mm/lib/edit_macro.py,sha256=raKWBwsHInj5EUKmvyLQ6gqc3ZFDlstsD3xqoM4PC8E,517
|
96
96
|
not1mm/lib/edit_opon.py,sha256=j3qJ1aBsQoIOnQ9yiBl3lyeISvKTP0I_rtBYBPAfgeI,359
|
97
97
|
not1mm/lib/edit_station.py,sha256=doL21Hs6jzIE43ohAopdFt_iqnRJZHFcqzcnCS0-iio,1965
|
98
|
+
not1mm/lib/ft8_watcher.py,sha256=rqvv7v2CXus0U8bekDenHvFVxFpYpzuApW-SA-SdtIA,4220
|
98
99
|
not1mm/lib/ham_utility.py,sha256=pUrysod3wGk4BYOWDAKJxZZTiUNDE4ZzRk8S5ZnllNA,10978
|
99
100
|
not1mm/lib/lookup.py,sha256=F2fl5QkMxaGSxl1XMWnLUub3T9Mt7LhCX4acOlAsks4,13952
|
100
101
|
not1mm/lib/multicast.py,sha256=bnFUNHyy82GmIb3_88EPBVVssj7-HzkJPaH671cK8Qw,3249
|
@@ -104,7 +105,7 @@ not1mm/lib/plugin_common.py,sha256=AAKBPCXzTWZJb-h08uPNnHVG7bSCg7kwukc211gFivY,8
|
|
104
105
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
105
106
|
not1mm/lib/settings.py,sha256=tlXlJUUZP0IFwIDc9DboM5_1by_tHNtMXvyJ0E7B6RI,8877
|
106
107
|
not1mm/lib/super_check_partial.py,sha256=p5l3u2ZOCBtlWgbvskC50FpuoaIpR07tfC6zTdRWbh4,2334
|
107
|
-
not1mm/lib/version.py,sha256=
|
108
|
+
not1mm/lib/version.py,sha256=Wes7CC0XEyDqpJ3xgXH1t9ppJBLckqKLy0EKZgu5ngs,47
|
108
109
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
109
110
|
not1mm/plugins/10_10_fall_cw.py,sha256=fUjfwjuscDjicXIxsO0JHh7xTR9Vu0iPsrOLb896Qak,10873
|
110
111
|
not1mm/plugins/10_10_spring_cw.py,sha256=WNaJP5mBQfaB6SxnFI0Vawt3AKDr94tKVtAK-EVhtUY,10878
|
@@ -138,9 +139,9 @@ not1mm/plugins/naqp_ssb.py,sha256=IWksulcb2_DxlkeW0h3048t8I-u00G_67KBVKkp-TV4,11
|
|
138
139
|
not1mm/plugins/phone_weekly_test.py,sha256=gCX0ESUoiQzDp9puwibt9-dRembNsiuEeBdawCVvjHA,12316
|
139
140
|
not1mm/plugins/stew_perry_topband.py,sha256=DIMI3mGMKokXXb9pPLqdhBI6JVnnIs7ZnAL23nFmshE,10588
|
140
141
|
not1mm/plugins/winter_field_day.py,sha256=4rcfRtobwjHO6BNL3WOTHzBmyyeuX79BNGBG8PfjrI8,10238
|
141
|
-
not1mm-24.4.
|
142
|
-
not1mm-24.4.
|
143
|
-
not1mm-24.4.
|
144
|
-
not1mm-24.4.
|
145
|
-
not1mm-24.4.
|
146
|
-
not1mm-24.4.
|
142
|
+
not1mm-24.4.9.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
143
|
+
not1mm-24.4.9.dist-info/METADATA,sha256=Pun0IV1Hor4GAcMYWJboFAr6Guotti9qDGDezoWi3l4,26819
|
144
|
+
not1mm-24.4.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
145
|
+
not1mm-24.4.9.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
146
|
+
not1mm-24.4.9.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
147
|
+
not1mm-24.4.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|