fix(wintest): replace unreliable band-limited AUTO sked mode detection with explicit SSB/CW selection and show exact KST callsigns in the timeline and fixed (#50 ensured Filter-Reset)

This commit is contained in:
Marc Froehlich
2026-08-07 22:56:24 +02:00
parent 4f574ebec6
commit 6a7f07c62e
5 changed files with 57 additions and 98 deletions
@@ -883,23 +883,29 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
); );
} }
String modeText = String configuredMode =
chatPreferences.getLogsynch_wintestSkedMode(); chatPreferences.getLogsynch_wintestSkedMode();
int modeOverride = -1; /*
* Win-Test mode IDs:
if ("CW".equalsIgnoreCase(modeText)) { * 0 = CW
modeOverride = 0; * 1 = SSB
} else if ("SSB".equalsIgnoreCase(modeText)) { *
modeOverride = 1; * SSB is the safe fallback for missing or obsolete settings.
} * The former AUTO mode was frequency-based and could not produce
* reliable results on every supported VHF, UHF and SHF band.
*/
int winTestMode =
"CW".equalsIgnoreCase(configuredMode)
? 0
: 1;
sender.pushSkedToWinTest( sender.pushSkedToWinTest(
sked, sked,
winTestCallsign, winTestCallsign,
frequencyKHz, frequencyKHz,
notes, notes,
modeOverride winTestMode
); );
} catch (Exception exception) { } catch (Exception exception) {
@@ -46,13 +46,13 @@ public class WinTestSkedSender {
* @param targetCallsign callsign prepared for Win-Test * @param targetCallsign callsign prepared for Win-Test
* @param frequencyKHz operating frequency in kHz * @param frequencyKHz operating frequency in kHz
* @param notes optional notes * @param notes optional notes
* @param modeOverride -1 for AUTO, 0 for CW, 1 for SSB * @param mode Win-Test mode ID: 0 for CW, 1 for SSB
*/ */
public void pushSkedToWinTest(ContestSked sked, public void pushSkedToWinTest(ContestSked sked,
String targetCallsign, String targetCallsign,
double frequencyKHz, double frequencyKHz,
String notes, String notes,
int modeOverride) { int mode) {
try { try {
sendLockSked(); sendLockSked();
@@ -62,7 +62,7 @@ public class WinTestSkedSender {
targetCallsign, targetCallsign,
frequencyKHz, frequencyKHz,
notes, notes,
modeOverride mode
); );
sendUnlockSked(); sendUnlockSked();
@@ -79,6 +79,8 @@ public class WinTestSkedSender {
+ frequencyKHz + frequencyKHz
+ " kHz, band=" + " kHz, band="
+ sked.getBand() + sked.getBand()
+ ", mode="
+ mode
); );
} catch (Exception exception) { } catch (Exception exception) {
@@ -131,7 +133,7 @@ public class WinTestSkedSender {
String targetCallsign, String targetCallsign,
double frequencyKHz, double frequencyKHz,
String notes, String notes,
int modeOverride) throws Exception { int mode) throws Exception {
long wtTimestamp = long wtTimestamp =
sked.getSkedTimeEpoch() / 1000L; sked.getSkedTimeEpoch() / 1000L;
@@ -143,21 +145,20 @@ public class WinTestSkedSender {
int bandId = int bandId =
toWinTestBandId(sked.getBand()); toWinTestBandId(sked.getBand());
int mode; /*
* Accept only the mode IDs supported by this UI.
if (modeOverride >= 0) { * Any unexpected value falls back to SSB.
mode = modeOverride; */
} else { int winTestMode =
mode = isInSsbSegment(frequencyKHz) mode == 0
? 1 ? 0
: 0; : 1;
}
String data = String data =
wtTimestamp wtTimestamp
+ " " + frequencyTenthKHz + " " + frequencyTenthKHz
+ " " + bandId + " " + bandId
+ " " + mode + " " + winTestMode
+ " \"" + targetCallsign + "\"" + " \"" + targetCallsign + "\""
+ " \"" + (notes != null ? notes : "") + "\""; + " \"" + (notes != null ? notes : "") + "\"";
@@ -211,18 +212,6 @@ public class WinTestSkedSender {
}; };
} }
/**
* Very simple SSB segment heuristic.
* A more complete implementation would check actual mode from Win-Test STATUS.
*/
private boolean isInSsbSegment(double frequencyKHz) {
// SSB segments (kHz ranges)
if (frequencyKHz >= 144300 && frequencyKHz <= 144399) return true; // 2m SSB
if (frequencyKHz >= 432200 && frequencyKHz <= 432399) return true; // 70cm SSB
if (frequencyKHz >= 1296200 && frequencyKHz <= 1296399) return true; // 23cm SSB
return false;
}
private void reportStatus(String text, boolean isError) { private void reportStatus(String text, boolean isError) {
if (callback != null) { if (callback != null) {
callback.onThreadStatus(THREAD_NICKNAME, callback.onThreadStatus(THREAD_NICKNAME,
@@ -224,7 +224,7 @@ public class ChatPreferences {
boolean logsynch_wintestNetworkListenerEnabled = true; // default true = bisheriges Verhalten boolean logsynch_wintestNetworkListenerEnabled = true; // default true = bisheriges Verhalten
String logsynch_wintestNetworkBroadcastAddress = "255.255.255.255"; // UDP broadcast address for sending to Win-Test String logsynch_wintestNetworkBroadcastAddress = "255.255.255.255"; // UDP broadcast address for sending to Win-Test
boolean logsynch_wintestNetworkSkedPushEnabled = false; // push SKEDs to Win-Test via UDP boolean logsynch_wintestNetworkSkedPushEnabled = false; // push SKEDs to Win-Test via UDP
String logsynch_wintestSkedMode = "SSB"; // CW, SSB or AUTO String logsynch_wintestSkedMode = "SSB"; // Supported values: SSB or CW
boolean logsynch_wintestQrgSyncEnabled = true; // sync QRG from Win-Test STATUS packet boolean logsynch_wintestQrgSyncEnabled = true; // sync QRG from Win-Test STATUS packet
boolean logsynch_wintestUsePassQrg = false; // use pass frequency instead of main QRG from STATUS packet boolean logsynch_wintestUsePassQrg = false; // use pass frequency instead of main QRG from STATUS packet
@@ -792,30 +792,33 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
} }
ChoiceBox<String> cbSkedMode = new ChoiceBox<>( ChoiceBox<String> cbSkedMode = new ChoiceBox<>(
FXCollections.observableArrayList("AUTO", "SSB", "CW") FXCollections.observableArrayList("SSB", "CW")
); );
String configuredSkedMode = String configuredSkedMode =
chatcontroller.getChatPreferences().getLogsynch_wintestSkedMode(); chatcontroller.getChatPreferences()
.getLogsynch_wintestSkedMode();
if (configuredSkedMode == null || configuredSkedMode.isBlank()) { if (configuredSkedMode == null
configuredSkedMode = "AUTO"; || (!"SSB".equalsIgnoreCase(configuredSkedMode)
&& !"CW".equalsIgnoreCase(configuredSkedMode))) {
configuredSkedMode = "SSB";
} }
String configuredSkedModeUpper = cbSkedMode.setValue(
configuredSkedMode.trim().toUpperCase(Locale.ROOT); configuredSkedMode.trim().toUpperCase(Locale.ROOT)
);
if (!"AUTO".equals(configuredSkedModeUpper) cbSkedMode.setTooltip(new Tooltip(
&& !"SSB".equals(configuredSkedModeUpper) "Mode transferred to Win-Test with the ADDSKED packet"
&& !"CW".equals(configuredSkedModeUpper)) { ));
configuredSkedModeUpper = "AUTO";
}
cbSkedMode.setValue(configuredSkedModeUpper);
cbSkedMode.setTooltip(new Tooltip("Mode for Win-Test ADDSKED packets"));
cbSkedMode.setOnAction(e -> cbSkedMode.setOnAction(e ->
chatcontroller.getChatPreferences() chatcontroller.getChatPreferences()
.setLogsynch_wintestSkedMode(cbSkedMode.getValue()) .setLogsynch_wintestSkedMode(
cbSkedMode.getValue()
)
); );
ChoiceBox<String> cbReminderOffsets = new ChoiceBox<>( ChoiceBox<String> cbReminderOffsets = new ChoiceBox<>(
@@ -7869,52 +7872,6 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
chatMemberTableFilterTextField.setPromptText("Find..."); chatMemberTableFilterTextField.setPromptText("Find...");
chatMemberTableFilterTextField.setFocusTraversable(false); chatMemberTableFilterTextField.setFocusTraversable(false);
// chatMemberTableFilterTextField.focusedProperty().addListener(new ChangeListener<Boolean>() {
// @Override
// public void changed(ObservableValue<? extends Boolean> observableValue, Boolean aBoolean, Boolean t1) {
// if (chatMemberTableFilterTextField.focusedProperty().getValue()) {
//
// chatMemberTableFilterTextField.clear();
// } else {
// if (!chatMemberTableFilterTextField.focusedProperty().getValue() && chatMemberTableFilterTextField.textProperty().equals("")) {
//
// chatMemberTableFilterTextField.setText("Find...");
// }
// }
//// System.out.println(chatMemberTableFilterTextField.focusedProperty().getValue());
// }
// });
// chatMemberTableFilterTextField.textProperty().addListener(new ChangeListener<String>() {
//
// Predicate<ChatMember> searchTextPredicate = new Predicate<ChatMember>() {
// @Override
// public boolean test(ChatMember chatMember) {
// if (chatMember.getCallSign().toUpperCase().contains(chatMemberTableFilterTextField.getText().toUpperCase()) ||
// chatMember.getCallSign().toUpperCase().contains(chatMemberTableFilterTextField.getText().toLowerCase())) {
// return true;
// } else
//
// return false;
// }
//
// };
//
// @Override
// public void changed(ObservableValue<? extends String> observableValue, String s, String t1) {
//
// if (chatMemberTableFilterTextField.textProperty().getValue().equals("") && !chatMemberTableFilterTextField.focusedProperty().getValue()) {
// chatMemberTableFilterTextField.setText("Find...");
// chatcontroller.getLst_chatMemberListFilterPredicates().remove(searchTextPredicate);
// }
// else {
// if (!chatcontroller.getLst_chatMemberListFilterPredicates().contains(searchTextPredicate)) {
// chatcontroller.getLst_chatMemberListFilterPredicates().add(searchTextPredicate);
// }
// }
//
// System.out.println("KST4CApp " + chatMemberTableFilterTextField.textProperty().getValue().equals("") + " / " + !chatMemberTableFilterTextField.focusedProperty().getValue());
// }
// });
chatMemberTableFilterTextField.textProperty().addListener(new ChangeListener<String>() { chatMemberTableFilterTextField.textProperty().addListener(new ChangeListener<String>() {
@@ -208,7 +208,12 @@ public class TimelineView extends Pane {
diamond.setFill(colorForPotential(sked.getOpportunityPotentialPercent())); diamond.setFill(colorForPotential(sked.getOpportunityPotentialPercent()));
String baseToolTipFallBack = sked.getTargetCallsign() + " (" + sked.getBand() + ")\nAz: " + sked.getTargetAzimuth(); String baseToolTipFallBack =
sked.getTargetChatCallsign()
+ " ("
+ sked.getBand()
+ ")\nAz: "
+ sked.getTargetAzimuth();
if (skedTooltipExtraTextProvider != null) { if (skedTooltipExtraTextProvider != null) {
String extra = skedTooltipExtraTextProvider.apply(sked); String extra = skedTooltipExtraTextProvider.apply(sked);
@@ -220,7 +225,9 @@ public class TimelineView extends Pane {
Tooltip t = new Tooltip(baseToolTipFallBack); Tooltip t = new Tooltip(baseToolTipFallBack);
Tooltip.install(diamond, t); Tooltip.install(diamond, t);
Label lbl = new Label("SKED: " + sked.getTargetCallsign()); Label lbl = new Label(
"SKED: " + sked.getTargetChatCallsign()
);
// lbl.setFont(new Font(9)); // lbl.setFont(new Font(9));
// lbl.setTextFill(Color.WHITE); // lbl.setTextFill(Color.WHITE);
lbl.setLayoutY(14); lbl.setLayoutY(14);