not1mm 24.5.1__py3-none-any.whl → 24.5.10__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 +18 -10
- not1mm/bandmap.py +3 -1
- not1mm/checkwindow.py +5 -1
- not1mm/data/new_contest.ui +5 -0
- not1mm/lib/playsound.py +296 -0
- not1mm/lib/version.py +1 -1
- not1mm/logwindow.py +5 -1
- not1mm/playsoundtest.py +15 -0
- not1mm/plugins/10_10_fall_cw.py +2 -0
- not1mm/plugins/10_10_spring_cw.py +2 -0
- not1mm/plugins/10_10_summer_phone.py +2 -0
- not1mm/plugins/10_10_winter_phone.py +2 -0
- not1mm/plugins/arrl_10m.py +2 -0
- not1mm/plugins/arrl_dx_cw.py +2 -0
- not1mm/plugins/arrl_dx_ssb.py +2 -0
- not1mm/plugins/arrl_ss_cw.py +2 -0
- not1mm/plugins/arrl_ss_phone.py +2 -0
- not1mm/plugins/arrl_vhf_jan.py +2 -0
- not1mm/plugins/arrl_vhf_jun.py +2 -0
- not1mm/plugins/arrl_vhf_sep.py +2 -0
- not1mm/plugins/canada_day.py +2 -0
- not1mm/plugins/cq_160_cw.py +2 -0
- not1mm/plugins/cq_160_ssb.py +2 -0
- not1mm/plugins/cq_wpx_cw.py +39 -0
- not1mm/plugins/cq_wpx_ssb.py +2 -0
- not1mm/plugins/cq_ww_cw.py +2 -0
- not1mm/plugins/cq_ww_ssb.py +2 -0
- not1mm/plugins/cwt.py +26 -0
- not1mm/plugins/general_logging.py +2 -0
- not1mm/plugins/iaru_hf.py +2 -0
- not1mm/plugins/icwc_mst.py +372 -0
- not1mm/plugins/jidx_cw.py +31 -0
- not1mm/plugins/jidx_ph.py +2 -0
- not1mm/plugins/naqp_cw.py +32 -0
- not1mm/plugins/naqp_ssb.py +2 -0
- not1mm/plugins/stew_perry_topband.py +2 -0
- not1mm/radio.py +15 -9
- not1mm/vfo.py +5 -1
- not1mm/voice_keying.py +3 -0
- {not1mm-24.5.1.dist-info → not1mm-24.5.10.dist-info}/METADATA +9 -3
- {not1mm-24.5.1.dist-info → not1mm-24.5.10.dist-info}/RECORD +45 -42
- {not1mm-24.5.1.dist-info → not1mm-24.5.10.dist-info}/LICENSE +0 -0
- {not1mm-24.5.1.dist-info → not1mm-24.5.10.dist-info}/WHEEL +0 -0
- {not1mm-24.5.1.dist-info → not1mm-24.5.10.dist-info}/entry_points.txt +0 -0
- {not1mm-24.5.1.dist-info → not1mm-24.5.10.dist-info}/top_level.txt +0 -0
not1mm/plugins/cq_ww_ssb.py
CHANGED
@@ -51,6 +51,8 @@ def interface(self):
|
|
51
51
|
self.field2.show()
|
52
52
|
self.field3.hide()
|
53
53
|
self.field4.show()
|
54
|
+
self.snt_label.setText("SNT")
|
55
|
+
self.field1.setAccessibleName("RST Sent")
|
54
56
|
label = self.field4.findChild(QtWidgets.QLabel)
|
55
57
|
label.setText("CQ Zone")
|
56
58
|
self.field4.setAccessibleName("C Q Zone")
|
not1mm/plugins/cwt.py
CHANGED
@@ -2,6 +2,30 @@
|
|
2
2
|
|
3
3
|
# pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member, unused-import
|
4
4
|
|
5
|
+
# CWops Test (CWT)
|
6
|
+
# Status: Active
|
7
|
+
# Geographic Focus: Worldwide
|
8
|
+
# Participation: Worldwide
|
9
|
+
# Awards: Worldwide
|
10
|
+
# Mode: CW
|
11
|
+
# Bands: 160, 80, 40, 20, 15, 10m
|
12
|
+
# Classes: Single Op (QRP/Low/High)
|
13
|
+
# Max power: HP: >100 watts
|
14
|
+
# LP: 100 watts
|
15
|
+
# QRP: 5 watts
|
16
|
+
# Exchange: Member: Name + Member No./"CWA"
|
17
|
+
# non-Member: Name + (state/province/country)
|
18
|
+
# Work stations: Once per band
|
19
|
+
# QSO Points: 1 point per QSO
|
20
|
+
# Multipliers: Each call once
|
21
|
+
# Score Calculation: Total score = total QSO points x total mults
|
22
|
+
# Post log summary at: http://www.3830scores.com
|
23
|
+
# Mail logs to: (none)
|
24
|
+
# Find rules at: https://cwops.org/cwops-tests/
|
25
|
+
# Cabrillo name: CW-OPS
|
26
|
+
# Cabrillo name aliases: CW-OPS-CWT
|
27
|
+
|
28
|
+
|
5
29
|
import datetime
|
6
30
|
import logging
|
7
31
|
|
@@ -52,6 +76,8 @@ def interface(self):
|
|
52
76
|
self.field2.show()
|
53
77
|
self.field3.show()
|
54
78
|
self.field4.show()
|
79
|
+
self.snt_label.setText("SNT")
|
80
|
+
self.field1.setAccessibleName("RST Sent")
|
55
81
|
label = self.field3.findChild(QtWidgets.QLabel)
|
56
82
|
label.setText("Name")
|
57
83
|
self.field3.setAccessibleName("Name")
|
@@ -43,6 +43,8 @@ def interface(self):
|
|
43
43
|
self.field2.show()
|
44
44
|
self.field3.show()
|
45
45
|
self.field4.show()
|
46
|
+
self.snt_label.setText("SNT")
|
47
|
+
self.field1.setAccessibleName("RST Sent")
|
46
48
|
label = self.field3.findChild(QtWidgets.QLabel)
|
47
49
|
label.setText("Name")
|
48
50
|
self.field3.setAccessibleName("Name")
|
not1mm/plugins/iaru_hf.py
CHANGED
@@ -67,6 +67,8 @@ def interface(self):
|
|
67
67
|
self.field2.show()
|
68
68
|
self.field3.hide()
|
69
69
|
self.field4.show()
|
70
|
+
self.snt_label.setText("SNT")
|
71
|
+
self.field1.setAccessibleName("RST Sent")
|
70
72
|
label = self.field4.findChild(QtWidgets.QLabel)
|
71
73
|
label.setText("ITU Zone")
|
72
74
|
self.field4.setAccessibleName("I T U Zone")
|
@@ -0,0 +1,372 @@
|
|
1
|
+
"""ICWC Medium Speed Test"""
|
2
|
+
|
3
|
+
# pylint: disable=invalid-name, c-extension-no-member, unused-import
|
4
|
+
|
5
|
+
|
6
|
+
# ICWC Medium Speed Test
|
7
|
+
# Status: Active
|
8
|
+
# Geographic Focus: Worldwide
|
9
|
+
# Participation: Worldwide
|
10
|
+
# Mode: CW
|
11
|
+
# Bands: 160, 80, 40, 20, 15, 10m
|
12
|
+
# Classes: Single Op (QRP/Low/High)
|
13
|
+
# Max power: HP: >100 watts
|
14
|
+
# LP: 100 watts
|
15
|
+
# QRP: 5 watts
|
16
|
+
# Exchange: Name + QSO No.
|
17
|
+
# Work stations: Once per band
|
18
|
+
# QSO Points: 1 point per QSO
|
19
|
+
# Multipliers: Each call once
|
20
|
+
# Score Calculation: Total score = total QSO points x total mults
|
21
|
+
# Post log summary at: http://www.3830scores.com
|
22
|
+
# Mail logs to: (none)
|
23
|
+
# Find rules at: https://internationalcwcouncil.org/mst-contest/
|
24
|
+
# Cabrillo name: ICWC-MST
|
25
|
+
|
26
|
+
# The final score can be calculated by counting 1 point per QSO
|
27
|
+
# (work a station once per band only) and multiplying total points
|
28
|
+
# by the number of unique callsigns worked
|
29
|
+
|
30
|
+
import datetime
|
31
|
+
import logging
|
32
|
+
|
33
|
+
from pathlib import Path
|
34
|
+
|
35
|
+
from PyQt6 import QtWidgets
|
36
|
+
|
37
|
+
from not1mm.lib.plugin_common import gen_adif, get_points
|
38
|
+
from not1mm.lib.version import __version__
|
39
|
+
|
40
|
+
logger = logging.getLogger(__name__)
|
41
|
+
|
42
|
+
EXCHANGE_HINT = "NAME"
|
43
|
+
|
44
|
+
name = "ICWC Medium Speed Test"
|
45
|
+
cabrillo_name = "ICWC-MST"
|
46
|
+
mode = "CW" # CW SSB BOTH RTTY
|
47
|
+
|
48
|
+
columns = [
|
49
|
+
"YYYY-MM-DD HH:MM:SS",
|
50
|
+
"Call",
|
51
|
+
"Freq",
|
52
|
+
"SentNr",
|
53
|
+
"Name",
|
54
|
+
"RcvNr",
|
55
|
+
"PTS",
|
56
|
+
]
|
57
|
+
|
58
|
+
advance_on_space = [True, True, True, True, True]
|
59
|
+
|
60
|
+
# 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
|
61
|
+
dupe_type = 2
|
62
|
+
|
63
|
+
|
64
|
+
def init_contest(self):
|
65
|
+
"""setup plugin"""
|
66
|
+
set_tab_next(self)
|
67
|
+
set_tab_prev(self)
|
68
|
+
interface(self)
|
69
|
+
self.next_field = self.other_1
|
70
|
+
|
71
|
+
|
72
|
+
def interface(self):
|
73
|
+
"""Setup user interface"""
|
74
|
+
self.field1.show()
|
75
|
+
self.field2.hide()
|
76
|
+
self.field3.show()
|
77
|
+
self.field4.show()
|
78
|
+
self.snt_label.setText("Sent S/N")
|
79
|
+
self.field1.setAccessibleName("Sent Serial Number")
|
80
|
+
self.other_label.setText("Name")
|
81
|
+
self.field3.setAccessibleName("Name")
|
82
|
+
self.exch_label.setText("S/N")
|
83
|
+
self.field4.setAccessibleName("Serial Number")
|
84
|
+
self.sent.setText("")
|
85
|
+
|
86
|
+
|
87
|
+
def reset_label(self): # pylint: disable=unused-argument
|
88
|
+
"""reset label after field cleared"""
|
89
|
+
|
90
|
+
|
91
|
+
def set_tab_next(self):
|
92
|
+
"""Set TAB Advances"""
|
93
|
+
self.tab_next = {
|
94
|
+
self.callsign: self.field1.findChild(QtWidgets.QLineEdit),
|
95
|
+
self.field1.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
96
|
+
QtWidgets.QLineEdit
|
97
|
+
),
|
98
|
+
# self.field2.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
99
|
+
# QtWidgets.QLineEdit
|
100
|
+
# ),
|
101
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
|
102
|
+
QtWidgets.QLineEdit
|
103
|
+
),
|
104
|
+
self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
def set_tab_prev(self):
|
109
|
+
"""Set TAB Advances"""
|
110
|
+
self.tab_prev = {
|
111
|
+
self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
|
112
|
+
self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
|
113
|
+
# self.field2.findChild(QtWidgets.QLineEdit): self.field1.findChild(
|
114
|
+
# QtWidgets.QLineEdit
|
115
|
+
# ),
|
116
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.field1.findChild(
|
117
|
+
QtWidgets.QLineEdit
|
118
|
+
),
|
119
|
+
self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
120
|
+
QtWidgets.QLineEdit
|
121
|
+
),
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
def set_contact_vars(self):
|
126
|
+
"""Contest Specific"""
|
127
|
+
self.contact["SNT"] = "599"
|
128
|
+
self.contact["RCV"] = "599"
|
129
|
+
self.contact["SentNr"] = self.sent.text()
|
130
|
+
self.contact["Name"] = self.other_1.text()
|
131
|
+
self.contact["NR"] = self.other_2.text()
|
132
|
+
|
133
|
+
|
134
|
+
def predupe(self): # pylint: disable=unused-argument
|
135
|
+
"""called after callsign entered"""
|
136
|
+
|
137
|
+
|
138
|
+
def prefill(self):
|
139
|
+
"""Fill SentNR"""
|
140
|
+
result = self.database.get_serial()
|
141
|
+
serial_nr = str(result.get("serial_nr", "1"))
|
142
|
+
if serial_nr == "None":
|
143
|
+
serial_nr = "1"
|
144
|
+
field = self.sent
|
145
|
+
if len(field.text()) == 0:
|
146
|
+
field.setText(serial_nr)
|
147
|
+
|
148
|
+
|
149
|
+
def points(self):
|
150
|
+
"""Calc point"""
|
151
|
+
return 1
|
152
|
+
|
153
|
+
|
154
|
+
def show_mults(self):
|
155
|
+
"""Return display string for mults"""
|
156
|
+
result = self.database.fetch_call_count()
|
157
|
+
if result:
|
158
|
+
return int(result.get("call_count", 0))
|
159
|
+
return 0
|
160
|
+
|
161
|
+
|
162
|
+
def show_qso(self):
|
163
|
+
"""Return qso count"""
|
164
|
+
result = self.database.fetch_qso_count()
|
165
|
+
if result:
|
166
|
+
return int(result.get("qsos", 0))
|
167
|
+
return 0
|
168
|
+
|
169
|
+
|
170
|
+
def calc_score(self):
|
171
|
+
"""Return calculated score"""
|
172
|
+
result = self.database.fetch_points()
|
173
|
+
if result is not None:
|
174
|
+
score = result.get("Points", "0")
|
175
|
+
if score is None:
|
176
|
+
score = "0"
|
177
|
+
contest_points = int(score)
|
178
|
+
mults = show_mults(self)
|
179
|
+
return contest_points * mults
|
180
|
+
return 0
|
181
|
+
|
182
|
+
|
183
|
+
def adif(self):
|
184
|
+
"""Call the generate ADIF function"""
|
185
|
+
gen_adif(self, cabrillo_name, "ICWC-MST")
|
186
|
+
|
187
|
+
|
188
|
+
def cabrillo(self):
|
189
|
+
"""Generates Cabrillo file. Maybe."""
|
190
|
+
logger.debug("******Cabrillo*****")
|
191
|
+
logger.debug("Station: %s", f"{self.station}")
|
192
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
193
|
+
now = datetime.datetime.now()
|
194
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
195
|
+
filename = (
|
196
|
+
str(Path.home())
|
197
|
+
+ "/"
|
198
|
+
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
|
199
|
+
)
|
200
|
+
logger.debug("%s", filename)
|
201
|
+
log = self.database.fetch_all_contacts_asc()
|
202
|
+
try:
|
203
|
+
with open(filename, "w", encoding="ascii") as file_descriptor:
|
204
|
+
print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
|
205
|
+
print(
|
206
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
207
|
+
end="\r\n",
|
208
|
+
file=file_descriptor,
|
209
|
+
)
|
210
|
+
print(
|
211
|
+
f"CONTEST: {cabrillo_name}",
|
212
|
+
end="\r\n",
|
213
|
+
file=file_descriptor,
|
214
|
+
)
|
215
|
+
if self.station.get("Club", ""):
|
216
|
+
print(
|
217
|
+
f"CLUB: {self.station.get('Club', '').upper()}",
|
218
|
+
end="\r\n",
|
219
|
+
file=file_descriptor,
|
220
|
+
)
|
221
|
+
print(
|
222
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
223
|
+
end="\r\n",
|
224
|
+
file=file_descriptor,
|
225
|
+
)
|
226
|
+
print(
|
227
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
228
|
+
end="\r\n",
|
229
|
+
file=file_descriptor,
|
230
|
+
)
|
231
|
+
# print(
|
232
|
+
# f"ARRL-SECTION: {self.pref.get('section', '')}",
|
233
|
+
# end="\r\n",
|
234
|
+
# file=file_descriptor,
|
235
|
+
# )
|
236
|
+
print(
|
237
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
238
|
+
end="\r\n",
|
239
|
+
file=file_descriptor,
|
240
|
+
)
|
241
|
+
print(
|
242
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
243
|
+
end="\r\n",
|
244
|
+
file=file_descriptor,
|
245
|
+
)
|
246
|
+
print(
|
247
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
248
|
+
end="\r\n",
|
249
|
+
file=file_descriptor,
|
250
|
+
)
|
251
|
+
print(
|
252
|
+
f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
|
253
|
+
end="\r\n",
|
254
|
+
file=file_descriptor,
|
255
|
+
)
|
256
|
+
print(
|
257
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
258
|
+
end="\r\n",
|
259
|
+
file=file_descriptor,
|
260
|
+
)
|
261
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
262
|
+
print(
|
263
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
264
|
+
end="\r\n",
|
265
|
+
file=file_descriptor,
|
266
|
+
)
|
267
|
+
print(
|
268
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
269
|
+
end="\r\n",
|
270
|
+
file=file_descriptor,
|
271
|
+
)
|
272
|
+
# print(
|
273
|
+
# f"CATEGORY: {None}",
|
274
|
+
# end="\r\n",
|
275
|
+
# file=file_descriptor,
|
276
|
+
# )
|
277
|
+
print(
|
278
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
279
|
+
end="\r\n",
|
280
|
+
file=file_descriptor,
|
281
|
+
)
|
282
|
+
|
283
|
+
print(
|
284
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
285
|
+
end="\r\n",
|
286
|
+
file=file_descriptor,
|
287
|
+
)
|
288
|
+
ops = f"@{self.station.get('Call','')}"
|
289
|
+
list_of_ops = self.database.get_ops()
|
290
|
+
for op in list_of_ops:
|
291
|
+
ops += f", {op.get('Operator', '')}"
|
292
|
+
print(
|
293
|
+
f"OPERATORS: {ops}",
|
294
|
+
end="\r\n",
|
295
|
+
file=file_descriptor,
|
296
|
+
)
|
297
|
+
print(
|
298
|
+
f"NAME: {self.station.get('Name', '')}",
|
299
|
+
end="\r\n",
|
300
|
+
file=file_descriptor,
|
301
|
+
)
|
302
|
+
print(
|
303
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
304
|
+
end="\r\n",
|
305
|
+
file=file_descriptor,
|
306
|
+
)
|
307
|
+
print(
|
308
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
309
|
+
end="\r\n",
|
310
|
+
file=file_descriptor,
|
311
|
+
)
|
312
|
+
print(
|
313
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
314
|
+
end="\r\n",
|
315
|
+
file=file_descriptor,
|
316
|
+
)
|
317
|
+
print(
|
318
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
319
|
+
end="\r\n",
|
320
|
+
file=file_descriptor,
|
321
|
+
)
|
322
|
+
print(
|
323
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
324
|
+
end="\r\n",
|
325
|
+
file=file_descriptor,
|
326
|
+
)
|
327
|
+
print(
|
328
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
329
|
+
end="\r\n",
|
330
|
+
file=file_descriptor,
|
331
|
+
)
|
332
|
+
for contact in log:
|
333
|
+
the_date_and_time = contact.get("TS", "")
|
334
|
+
themode = contact.get("Mode", "")
|
335
|
+
if themode == "LSB" or themode == "USB":
|
336
|
+
themode = "PH"
|
337
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
338
|
+
|
339
|
+
loggeddate = the_date_and_time[:10]
|
340
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
341
|
+
print(
|
342
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
343
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
344
|
+
f"{self.contest_settings.get('SentExchange', '').ljust(14).upper()}"
|
345
|
+
f"{str(contact.get('SentNr', '')).ljust(6)} "
|
346
|
+
f"{contact.get('Call', '').ljust(13)} "
|
347
|
+
f"{str(contact.get('Name', '')).ljust(14)} "
|
348
|
+
f"{str(contact.get('NR', '')).ljust(6)}",
|
349
|
+
end="\r\n",
|
350
|
+
file=file_descriptor,
|
351
|
+
)
|
352
|
+
print("END-OF-LOG:", end="\r\n", file=file_descriptor)
|
353
|
+
self.show_message_box(f"Cabrillo saved to: {filename}")
|
354
|
+
except IOError as exception:
|
355
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
356
|
+
self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
|
357
|
+
return
|
358
|
+
|
359
|
+
|
360
|
+
def recalculate_mults(self):
|
361
|
+
"""Recalculates multipliers after change in logged qso."""
|
362
|
+
# all_contacts = self.database.fetch_all_contacts_asc()
|
363
|
+
# for contact in all_contacts:
|
364
|
+
# time_stamp = contact.get("TS", "")
|
365
|
+
# wpx = contact.get("WPXPrefix", "")
|
366
|
+
# result = self.database.fetch_wpx_exists_before_me(wpx, time_stamp)
|
367
|
+
# wpx_count = result.get("wpx_count", 1)
|
368
|
+
# if wpx_count == 0:
|
369
|
+
# contact["IsMultiplier1"] = 1
|
370
|
+
# else:
|
371
|
+
# contact["IsMultiplier1"] = 0
|
372
|
+
# self.database.change_contact(contact)
|
not1mm/plugins/jidx_cw.py
CHANGED
@@ -2,6 +2,35 @@
|
|
2
2
|
|
3
3
|
# pylint: disable=invalid-name, unused-variable, c-extension-no-member
|
4
4
|
|
5
|
+
# JIDX CW Contest
|
6
|
+
# Status: Active
|
7
|
+
# Geographic Focus: Japan
|
8
|
+
# Participation: Worldwide
|
9
|
+
# Mode: CW
|
10
|
+
# Bands: 160, 80, 40, 20, 15, 10m
|
11
|
+
# Classes: Single Op All Band (Low/High)
|
12
|
+
# Single Op Single Band (Low/High)
|
13
|
+
# Multi-Single
|
14
|
+
# Multi-Two
|
15
|
+
# Maritime Mobile
|
16
|
+
# Max power: HP: >100W
|
17
|
+
# LP: 100W
|
18
|
+
# Exchange: JA: RST + Prefecture No.
|
19
|
+
# non-JA: RST + CQ Zone No.
|
20
|
+
# Work stations: Once per band
|
21
|
+
# QSO Points: 4 points per JA-DX QSO on 160m
|
22
|
+
# 2 points per JA-DX QSO on 80m
|
23
|
+
# 1 points per JA-DX QSO on 40, 20, 15m
|
24
|
+
# 2 points per JA-DX QSO on 10m
|
25
|
+
# Multipliers: JA Stations: DXCC countries and CQ zones once per band
|
26
|
+
# non-JA Stations: JA prefectures plus JD1/O, JD1/MT, JD1/OT once per band
|
27
|
+
# Score Calculation: Total score = total QSO points x total mults
|
28
|
+
# E-mail logs to: cw[at]jidx[dot]org
|
29
|
+
# Upload log at: http://www.jidx.org/upload/uplog.html
|
30
|
+
# Mail logs to: (none)
|
31
|
+
# Find rules at: http://www.jidx.org/jidxrule-e.html
|
32
|
+
# Cabrillo name: JIDX-CW
|
33
|
+
|
5
34
|
import datetime
|
6
35
|
import logging
|
7
36
|
|
@@ -52,6 +81,8 @@ def interface(self):
|
|
52
81
|
self.field2.show()
|
53
82
|
self.field3.show()
|
54
83
|
self.field4.show()
|
84
|
+
self.snt_label.setText("SNT")
|
85
|
+
self.field1.setAccessibleName("RST Sent")
|
55
86
|
label = self.field3.findChild(QtWidgets.QLabel)
|
56
87
|
label.setText("SentNR")
|
57
88
|
self.field3.setAccessibleName("Sent Number")
|
not1mm/plugins/jidx_ph.py
CHANGED
@@ -52,6 +52,8 @@ def interface(self):
|
|
52
52
|
self.field2.show()
|
53
53
|
self.field3.show()
|
54
54
|
self.field4.show()
|
55
|
+
self.snt_label.setText("SNT")
|
56
|
+
self.field1.setAccessibleName("RST Sent")
|
55
57
|
label = self.field3.findChild(QtWidgets.QLabel)
|
56
58
|
label.setText("SentNR")
|
57
59
|
self.field3.setAccessibleName("Sent Number")
|
not1mm/plugins/naqp_cw.py
CHANGED
@@ -2,6 +2,36 @@
|
|
2
2
|
|
3
3
|
# pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member, unused-import
|
4
4
|
|
5
|
+
# North American QSO Party, CW
|
6
|
+
# Status: Active
|
7
|
+
# Geographic Focus: North America
|
8
|
+
# Participation: Worldwide
|
9
|
+
# Awards: North America
|
10
|
+
# Mode: CW
|
11
|
+
# Bands: 160, 80, 40, 20, 15, 10m
|
12
|
+
# Classes: Single Op (QRP/Low)
|
13
|
+
# Single Op Assisted (QRP/Low)
|
14
|
+
# Single Op Overlay: Youth
|
15
|
+
# Multi-Two (Low)
|
16
|
+
# Max operating hours: Single Op: 10 hours
|
17
|
+
# Multi-Two: 12 hours
|
18
|
+
# Max power: LP: 100 watts
|
19
|
+
# QRP: 5 watts
|
20
|
+
# Exchange: NA: Name + (state/DC/province/country)
|
21
|
+
# non-NA: Name
|
22
|
+
# Work stations: Once per band
|
23
|
+
# QSO Points: NA station: 1 point per QSO
|
24
|
+
# non-NA station: 1 point per QSO with an NA station
|
25
|
+
# Multipliers: Each US state and DC (including KH6/KL7) once per band
|
26
|
+
# Each VE province/territory once per band
|
27
|
+
# Each North American country (except W/VE) once per band
|
28
|
+
# Score Calculation: Total score = total QSO points x total mults
|
29
|
+
# E-mail logs to: (none)
|
30
|
+
# Upload log at: http://www.ncjweb.com/naqplogsubmit/
|
31
|
+
# Mail logs to: (none)
|
32
|
+
# Find rules at: https://www.ncjweb.com/NAQP-Rules.pdf
|
33
|
+
# Cabrillo name: NAQP-CW
|
34
|
+
|
5
35
|
import datetime
|
6
36
|
import logging
|
7
37
|
import platform
|
@@ -51,6 +81,8 @@ def interface(self):
|
|
51
81
|
self.field2.hide()
|
52
82
|
self.field3.show()
|
53
83
|
self.field4.show()
|
84
|
+
self.snt_label.setText("SNT")
|
85
|
+
self.field1.setAccessibleName("RST Sent")
|
54
86
|
namefield = self.field3.findChild(QtWidgets.QLabel)
|
55
87
|
namefield.setText("Name")
|
56
88
|
self.field3.setAccessibleName("Name")
|
not1mm/plugins/naqp_ssb.py
CHANGED
@@ -51,6 +51,8 @@ def interface(self):
|
|
51
51
|
self.field2.hide()
|
52
52
|
self.field3.show()
|
53
53
|
self.field4.show()
|
54
|
+
self.snt_label.setText("SNT")
|
55
|
+
self.field1.setAccessibleName("RST Sent")
|
54
56
|
namefield = self.field3.findChild(QtWidgets.QLabel)
|
55
57
|
namefield.setText("Name")
|
56
58
|
self.field3.setAccessibleName("Name")
|
@@ -74,6 +74,8 @@ def interface(self):
|
|
74
74
|
self.field2.show()
|
75
75
|
self.field3.show()
|
76
76
|
self.field4.hide()
|
77
|
+
self.snt_label.setText("SNT")
|
78
|
+
self.field1.setAccessibleName("RST Sent")
|
77
79
|
label = self.field3.findChild(QtWidgets.QLabel)
|
78
80
|
label.setText("Grid")
|
79
81
|
self.field3.setAccessibleName("Grid")
|
not1mm/radio.py
CHANGED
@@ -12,7 +12,7 @@ GPL V3
|
|
12
12
|
import datetime
|
13
13
|
import logging
|
14
14
|
|
15
|
-
from PyQt6.QtCore import QObject, pyqtSignal, QThread
|
15
|
+
from PyQt6.QtCore import QObject, pyqtSignal, QThread, QEventLoop
|
16
16
|
from not1mm.lib.cat_interface import CAT
|
17
17
|
|
18
18
|
logger = logging.getLogger("cat_interface")
|
@@ -55,6 +55,9 @@ class Radio(QObject):
|
|
55
55
|
vfoa = self.cat.get_vfo()
|
56
56
|
self.online = False
|
57
57
|
if vfoa:
|
58
|
+
if not vfoa.isnumeric():
|
59
|
+
logger.debug(f"Bad VFOA data {vfoa=}")
|
60
|
+
continue
|
58
61
|
self.vfoa = vfoa
|
59
62
|
self.online = True
|
60
63
|
mode = self.cat.get_mode()
|
@@ -65,14 +68,17 @@ class Radio(QObject):
|
|
65
68
|
if bw:
|
66
69
|
self.bw = bw
|
67
70
|
self.online = True
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
try:
|
72
|
+
self.poll_callback.emit(
|
73
|
+
{
|
74
|
+
"vfoa": self.vfoa,
|
75
|
+
"mode": self.mode,
|
76
|
+
"bw": self.bw,
|
77
|
+
"online": self.online,
|
78
|
+
}
|
79
|
+
)
|
80
|
+
except QEventLoop:
|
81
|
+
...
|
76
82
|
QThread.msleep(100)
|
77
83
|
|
78
84
|
def sendcw(self, texttosend):
|
not1mm/vfo.py
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
"""
|
3
|
-
|
3
|
+
not1mm Contest logger
|
4
|
+
Email: michael.bridak@gmail.com
|
5
|
+
GPL V3
|
6
|
+
Class: VfoWindow
|
7
|
+
Purpose: Provide onscreen widget that interacts with DIY VFO knob and remote rig.
|
4
8
|
"""
|
5
9
|
# pylint: disable=no-name-in-module, unused-import, no-member, invalid-name, logging-fstring-interpolation, c-extension-no-member
|
6
10
|
|
not1mm/voice_keying.py
CHANGED
@@ -4,6 +4,9 @@
|
|
4
4
|
Not1MM Contest logger
|
5
5
|
Email: michael.bridak@gmail.com
|
6
6
|
GPL V3
|
7
|
+
Class: Voice
|
8
|
+
Purpose: A voice keying class to handle playing soundfiles and activating PTT
|
9
|
+
Run in it's own thread.
|
7
10
|
"""
|
8
11
|
|
9
12
|
# pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version: 24.5.
|
3
|
+
Version: 24.5.10
|
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
|
@@ -169,6 +169,7 @@ I wish to thank those who've contributed to the project.
|
|
169
169
|
- CQ World Wide SSB
|
170
170
|
- CWOps CWT
|
171
171
|
- IARU HF
|
172
|
+
- ICWC MST
|
172
173
|
- Japan International DX CW
|
173
174
|
- Japan International DX SSB
|
174
175
|
- NAQP CW
|
@@ -180,6 +181,8 @@ I wish to thank those who've contributed to the project.
|
|
180
181
|
|
181
182
|
## Recent Changes
|
182
183
|
|
184
|
+
- [24-5-10] Add sanity check for VFO freq.
|
185
|
+
- [24-5-9] Add ICWC MST.
|
183
186
|
- [24-5-1] Moved the voice keying into it's own thread.
|
184
187
|
|
185
188
|
See [CHANGELOG.md](CHANGELOG.md) for prior changes.
|
@@ -212,8 +215,11 @@ noted the minimum steps needed to install not1mm.
|
|
212
215
|
```bash
|
213
216
|
sudo apt update
|
214
217
|
sudo apt upgrade
|
215
|
-
sudo apt install -y
|
216
|
-
pip install -U
|
218
|
+
sudo apt install -y python3-pip python3-numpy libxcb-cursor0 libportaudio2
|
219
|
+
python3 -m pip install -U pip
|
220
|
+
# Logout and back in
|
221
|
+
pip3 install PyQt6
|
222
|
+
pip3 install not1mm
|
217
223
|
```
|
218
224
|
|
219
225
|
#### Ubuntu 23.04
|