not1mm 24.4.4.1__py3-none-any.whl → 24.4.8__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 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-64.png"))
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
 
@@ -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,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.4.4.1"
3
+ __version__ = "24.4.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 24.4.4.1
3
+ Version: 24.4.8
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,7 @@ I wish to thank those who've contributed to the project.
177
177
 
178
178
  ## Recent Changes
179
179
 
180
+ - [24-4-7] Added FT8Watcher class to prep for FT8 support.
180
181
  - [24-4-4-1] Made docking widgets open state persistent.
181
182
  - [24-4-4] Added per-contest echange hint when adding new contest.
182
183
  - [24-4-2] Migrated to PyQt6. I'm sure there are broken things.
@@ -1,5 +1,5 @@
1
1
  not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- not1mm/__main__.py,sha256=B-r1r8Do8Vw4FsyzgyB4P_KPU9LTlNTrmueknGmmI28,121967
2
+ not1mm/__main__.py,sha256=3Bjmi5rr_yuJHSdMNNc26skepG40crADyIppNqKUdu8,122807
3
3
  not1mm/bandmap.py,sha256=-wHbUmj-zqefyFO_ydLECwTtWcs37tSkA7Xm2zOVcLA,34318
4
4
  not1mm/checkwindow.py,sha256=ncIOZmuhM_eLR1gb-St8FqEefbUkD9p9VltFDJVxLeY,10465
5
5
  not1mm/fsutils.py,sha256=Li8Tq9K7c_q7onOHOQ7u1dOOFfhIIz5Aj2LKuQtGOO4,1652
@@ -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=_FQGpyHUssH34gTKJKt464g2di65ZgL7GI1Ug-H6BCs,49
108
+ not1mm/lib/version.py,sha256=STPOMn2n-xW7ukFItJ4ju86aXQxaBtskG8gPdqediQk,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.4.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
142
- not1mm-24.4.4.1.dist-info/METADATA,sha256=o_y3YMD6rXzqQejTEeOdxVbusU6Ige_Mj-IWF9No2Fo,26693
143
- not1mm-24.4.4.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
144
- not1mm-24.4.4.1.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
145
- not1mm-24.4.4.1.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
146
- not1mm-24.4.4.1.dist-info/RECORD,,
142
+ not1mm-24.4.8.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
143
+ not1mm-24.4.8.dist-info/METADATA,sha256=J4EAMhz2Bh-79rMLBXavJhMr0LHDxf-otsgz--OL8Gg,26750
144
+ not1mm-24.4.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
145
+ not1mm-24.4.8.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
146
+ not1mm-24.4.8.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
147
+ not1mm-24.4.8.dist-info/RECORD,,