Add Win-Test SKED push via UDP (ported from wtKST)

Implements sending SKEDs to Win-Test via the LOCKSKED/ADDSKED/UNLOCKSKED
UDP protocol sequence, ported from the C# wtSked class in wtKST.

New files:
- WinTestMessage.java: Win-Test network message format with checksum
- WinTestSkedSender.java: UDP broadcast sender for SKED messages

Modified:
- ChatController: addSked() now pushes to Win-Test when enabled
- ChatPreferences: new settings for broadcast address and sked push toggle

The feature is disabled by default (logsynch_wintestNetworkSkedPushEnabled=false).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 23:35:35 +01:00
committed by Rsclub2_2
co-authored by Claude Opus 4.6
parent 1f3aa031c3
commit c0b8aa61a9
4 changed files with 341 additions and 1 deletions
@@ -824,7 +824,50 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
Platform.runLater(() -> {
this.activeSkeds.add(sked);
scoreService.requestRecompute("sked-added");
}); //TODO: Addsked muss noch genutzt werden
});
// Push sked to Win-Test via UDP if enabled
if (chatPreferences.isLogsynch_wintestNetworkSkedPushEnabled()
&& chatPreferences.isLogsynch_wintestNetworkListenerEnabled()) {
pushSkedToWinTest(sked);
}
}
/**
* Pushes a sked to Win-Test via UDP broadcast (LOCKSKED / ADDSKED / UNLOCKSKED).
* Runs on a background thread to avoid blocking the UI.
*/
private void pushSkedToWinTest(ContestSked sked) {
new Thread(() -> {
try {
InetAddress broadcastAddr = InetAddress.getByName(
chatPreferences.getLogsynch_wintestNetworkBroadcastAddress());
int port = chatPreferences.getLogsynch_wintestNetworkPort();
String stationName = chatPreferences.getLogsynch_wintestNetworkStationNameOfKST();
WinTestSkedSender sender = new WinTestSkedSender(stationName, broadcastAddr, port, this);
// Get current frequency from QRG property (set by Win-Test STATUS or user)
double freqKHz = 144300.0; // fallback default
try {
String qrgStr = chatPreferences.getMYQRGFirstCat().get();
if (qrgStr != null && !qrgStr.isBlank()) {
freqKHz = Double.parseDouble(qrgStr.trim());
}
} catch (NumberFormatException ignored) { }
// Build notes string with locator/azimuth info
String notes = "sked via KST4Contest";
if (sked.getTargetAzimuth() > 0) {
notes = String.format("[%.0f°] %s", sked.getTargetAzimuth(), notes);
}
sender.pushSkedToWinTest(sked, freqKHz, notes);
} catch (Exception e) {
System.out.println("[ChatController] Error pushing sked to Win-Test: " + e.getMessage());
e.printStackTrace();
}
}, "WinTestSkedPush").start();
}
public StationMetricsService getStationMetricsService() {