mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-10-19 05:42:58 +02:00
* Make DBController work on one database file per instance The controller was a static singleton: an eagerly created static instance opened the root database during class initialization, and both the connection and the path were static fields. A second operator profile in the same process was therefore impossible, and ChatController's own "new DBController()" never opened anything - it silently adopted the eagerly opened root connection. - drop the eager static instance in favour of a lazily created default instance - turn connection and path into instance state - add a constructor taking a database file name relative to the application directory plus a flag whether a missing file is seeded from the bundled template - create additional profile databases empty instead of seeding them: the bundled template carries 3452 foreign callsigns and user_version 0, which would show a new operator foreign data and trigger the full callsign normalization rebuild. The schema is created by the existing table setup. - remember the shutdown hook so closeDBConnection can deregister it; otherwise every profile switch would leave another hook holding a dead connection All SQL statements keep referencing the plain field and are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Allow preferences and chat controller to be bound to a file set ChatPreferences gains a constructor taking a preferences file name relative to the application directory, so "profiles/OP2/preferences.xml" is as valid as the historic flat "preferences.xml". A missing file is still seeded from the bundled template, which gives an additional operator the same clean defaults a first installation gets. ChatController gains a constructor that passes both relative file names and the seed flag through to ChatPreferences and DBController. The existing constructors delegate to the historic file names, so nothing changes yet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Introduce the operator profile model and its registry Adds the descriptor, the path derivation and the registry persistence for operator profiles. Nothing calls them yet, so behaviour is unchanged. The descriptor stores only a shared/own flag, never a path. All file names are derived in OperatorProfilePaths, so a stored path can never drift apart from the flag that produced it. A profile identifier is a stable, file system safe slug assigned once, so renaming a profile never moves a directory. The registry is created lazily. An installation that only has the historic flat layout gets no registry file and no profiles directory; the root profile is synthesised in memory instead. That keeps a single operator installation byte for byte the one it was before, and it keeps a downgrade to an older release a no-op. A missing, unreadable or malformed registry is logged and treated like an installation without additional profiles, never as an error. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Select the operator profile at startup Resolves the active operator profile before the chat controller is built and passes its two file names on, so preferences, layout and worked data follow the profile. The resolution is deliberately quiet for existing installations. With no registry or exactly one profile nothing is asked and nothing is written, so a single operator start is unchanged. Only from two profiles on does a small picker appear with the last used profile preselected, where Enter or a double click starts immediately. A "--profile" argument, or the equivalent system property, skips the picker; an unknown name warns and falls back to the normal selection instead of refusing to start. The startup decision itself lives in OperatorProfileBootstrap and contains no user interface code, so it is covered by headless tests. The window title gains the profile name only when a second profile exists. Command line parsing happens in init() and is kept in a process wide holder, because JavaFX only knows the parameters of the instance it launched itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Release the background resources a discarded runtime owns Several resources outlived a disconnect on purpose, which was harmless while a process ran exactly one session for its whole life. They are now released when the controller itself is closed: - the ON4KST connection supervisor thread, which stopByUser did not touch - the sked reminder scheduler, which had no shutdown at all - the reachability executor, whose shutdown method existed but was never called - the PSTRotator retry scheduler and its pending retry - the map tile proxy, whose stop method existed but was never called, leaving a server socket and a twelve thread pool behind - the station map bridge listeners and its coalescing animation, which would otherwise keep firing into a dead user interface These are real leaks today; they only become visible when a second runtime is built in the same process. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Switch the operator profile while the application is running Splits the teardown out of stop() into a reusable, idempotent shutdownRuntime() and adds File - Switch operator profile..., which tears the current runtime down and builds a fresh one for the selected profile. The new runtime is a new application instance rather than a second start() on the existing one. Many controls are instance fields created once, so reusing the instance would re-parent mounted nodes and register every listener twice. A fresh instance is safe because the class keeps no mutable static state. Closing every window during a switch would end the process under the JavaFX default, so the application takes over the exit decision: implicit exit is turned off, the main window gets an explicit close handler, and every exit path runs through the launcher. That also fixes losing the window layout on exit after a switch, because JavaFX only calls stop() on the instance it launched. The two view timers are now cancelled null-safe; stop() used to dereference them unguarded, which would fail if shutdown happened before they were created. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Manage operator profiles from the settings window Adds a "Profiles" tab, appended last so no established tab position shifts, offering create, duplicate, rename, delete, a switch between shared and own worked stations, and activation of another profile. Duplicating copies the whole configuration except callsign and password. The antenna, locator, layout and integration settings are exactly the work nobody wants to enter twice, while the credentials belong to one operator only. The root profile can neither be deleted nor moved off the common station database, because its files are the installation itself. The login callsign and its raw form now default to empty instead of a real callsign. The XML reader treats an empty element as "not set" and falls back to the field default, so without this change a profile created without credentials would come up carrying the callsign compiled into the defaults - and an operator could transmit under someone else's call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Document operator profiles Adds a manual section in both languages covering where profile files live, the choice between shared and own worked stations, managing profiles, the startup selection and the --profile argument, switching while running, and the fact that passwords stay in clear text so profiles are not an access boundary. Records the architecture in PROJECT_CONTEXT: lazy registry, derived paths, why an additional profile database is created empty, why the login callsign default is empty, and the constraints of rebuilding the runtime for a switch. Adds a v1.50 changelog entry in both languages including the upgrade notes: no file is moved, and going back to an older release stays possible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Make the terrain profile cache multi operator safe The cache stored a single owner identity in a meta table and dropped the whole TerrainProfileCache table whenever the configured callsign or locator differed from it. With several operator profiles that turns the cache into a permanent miss: every switch between two operators with different locators would discard every computed profile. Entries are separated by owner identity through the primary key already, so the wipe is replaced by an owner table that simply records which identities are in use. A different owner now misses the cache instead of clearing everybody's. The cache also moves out of the worked station database into its own global terrainprofilecache.db. Terrain profiles are pure geometry derived from two locators and a sample count; at a multi operator station both operators share one location, so a per profile copy would only double the traffic against the terrain service. No migration is needed, the new file refills itself, and the old tables stay readable for older releases. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Fail cleanly when the registry path has no directory SpotBugs flagged a null passed to Files.createTempFile: the null check guarded only createDirectories, while the temporary file creation would still have dereferenced it. The path is resolved absolute so this is practically unreachable, but bailing out with a log line is cheaper than the latent NPE. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Code Version 1.50 * Add the in-app update concept for 1.50 Captures the agreed design so it can be handed over later: extended update feed with per-artifact metadata, a build-time package-type marker, a testable check service replacing the blocking call in the ChatController constructor, a non-modal hint suppressed while connected to ON4KST, verified downloads and platform-specific execution. Concept only, nothing implemented yet. Line anchors were verified against this branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HT8R7zTMoQnmJj6dGbaqqf * Use one base font size and a per-profile startup design JavaFX picks a 13px default font on macOS and Linux but 12px on Windows, so labels in fixed-size controls were cut off outside Windows. Both stylesheets now set 12px on the root. Each operator profile now chooses light or dark mode for startup on the GUI settings tab. The Windows menu entries remain a quick switch for the running session. All windows, including the update window and the top candidates list, follow the design, and the main window no longer starts light while the station map starts dark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Show a drag-to-install layout in the macOS DMG The DMG window now has a background with an arrow from the app to the Applications folder, in the KST4Contest colours. Finder applies the layout through AppleScript; if that fails, e.g. on a headless runner, the script warns and builds the plain DMG as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Use the macOS system menu bar in all windows On macOS the main menus move into the system menu bar and are shared with the secondary windows, so they stay available whichever window has the focus. The connection state indicator becomes a read-only LINK menu there instead of the status bar button. Other platforms are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * List direct commits on main in the release notes GitHub's generated release notes only cover merged pull requests, so commits pushed straight to main were missing. The release job now builds the notes itself: "What's Changed" holds "Commits on main" (first-parent, without bot and squash-merge commits) and GitHub's PR list as "Merged PRs". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Build with Gradle in two modules, and free core of JavaFX Etappen 1 and 2 of the Compose migration (43 commits). The Maven build, the single source tree and the JPMS module-info went together. core now holds the domain and app-desktop the user interface, both built by Gradle, packaged through jpackage from Gradle, with SpotBugs and PMD wired in. JavaFX moves to the classpath, which is why the launcher is Main and not the Application subclass. The PR check, the nightly artifacts, the release and the AUR packages all build from Gradle; the macOS DMG points at its output. Verified on Linux, macOS and Windows. core then loses JavaFX entirely. It observes through kst4contest.observe -- ObservableValue, ObservableRoster, and UiDispatcher as the one boundary a worker thread crosses to touch the interface. The controller collections become rosters and the visible station list a pure derivation rather than a FilteredList/SortedList chain, which is also what fixed two focus defects only a load test had exposed: the keyboard focus stays where the operator put it, and the send field keeps it after a row click. The rule that outlives this commit: ObservableRoster is the store and the list a view is bound to is a mirror of it, never the other way round. * Draw the whole interface in Compose Etappen 3 to 6a of the migration (129 commits). Every window the operator sees is Compose; the JavaFX ones still exist beside them so the two could be compared against a live session, which is the only way the differences came to light. The toolchain first, then the settings window with its eleven tabs and 72 real preferences; then the multi-column table as a component, and with it the rules it needs -- stable row identity, a selection that survives a refresh, column order the operator can drag, and a repaint when the rows change rather than when the list instance does. Then the update and monitor windows, and the main window: 22 station columns, the filter bar, the selected-station panel, the message tabs, the priority bar, the sked controls, the status indicators and the timeline, assembled behind a splitter because Compose has none. The map stops being a WebView. A Compose canvas projects WebMercator tiles itself, with the clustering in core and an asynchronous fetcher in place of the local tile proxy; derive() becomes a pure Kotlin reimplementation instead of a reflection call into com.sun.javafx. Most of the volume here is parity the operator would notice rather than new behaviour: desktop density instead of Material's phone minimums, colours taken from the JavaFX stylesheets instead of Material's palette, row dividers, band columns, grid-square labels and their colours, the home marker and antenna beam, pinch-to-zoom under Wayland, and layouts that survive a window narrower than the chart they stack. Two lessons are worth more than the diff. A control bound to a value Compose cannot observe writes through and never redraws -- that one shipped repeatedly with a green build, because no test drew anything. And a layout that clips instead of wrapping is worse than one that is merely too narrow: half a word is the worst available outcome. * Remove JavaFX The second half of Etappe 6 (61 commits). grep -rl "javafx\." over both main source trees is empty, nothing imports javafx, neither classpath resolves it, and org.openjfx is out of the build and the version catalog. The finding that shaped the work: the JavaFX main window was built on every start and never shown -- primaryStage's setScene and show were both commented out. Most of those 11,655 lines were dead weight rather than a port. But not all of them, and that is the trap this commit is really about: dead-looking methods still fed live Compose sinks. They were cut at their seams instead of deleted, and a sweep script that follows calls was written to find them, because reading the code does not reveal them. In order: the colour derivation frozen as checked-in test data, so the pin survives JavaFX being removed instead of silently comparing against itself; the live feeds lifted out of the never-shown window and given names and tests; the dead scaffolding deleted in slices; then the lifecycle. UiDispatcher now delivers to the AWT event dispatch thread, the ten Alerts are modal Compose dialogs, HostServices gives way to java.awt.Desktop with the mailto/http split JavaFX did not need, and extends Application, start(Stage), stop and launch are gone -- main builds the runtime and a shutdown hook replaces stop(). An independent review found two deadlocks in that move, both the same failure class, both invisible to the build: a blocking wait on the event thread for work that can only advance on the event thread. The profile picker waited on a latch and froze the client for good; ComposeWindowHost.close waited on Thread.join and returned with the window still marked open, which made a profile switch raise the dead runtime's window and leave the rebuilt profile without its Connect button. A third came out of fixing them: a ComposeDialog built off the event thread cannot create its GL context and never paints. Three defects only a GUI run showed, never the build: an NPE on a deleted field, a Compose menu still hanging on deleted MenuItems, and a category bookkeeping field that looked dead but is read by the outgoing-message category resolution -- deleting it would have sent messages in the wrong category. The binding docs and the manual no longer describe a JavaFX client. * Draw the menu bar in Compose, and give the drawing layer a net What the removal left open (4 commits). Compose's MenuBar is a javax.swing.JMenuBar set on the window, so Swing draws it and no theme reaches it; with no look-and-feel configured that meant the default Metal menu above a themed window. The bar is drawn in the window now, except on macOS, where the system bar is where that platform expects it. Two renderers read one description -- mainMenuModel is a plain function of the state, which also gives the menus their first tests. Closing the main window quits the application again, and the window writes its size back to the profile; both had quietly stopped working when the last JavaFX stage went. Then Etappe 7. Four faults shipped in the settings-window branch alongside a green suite of 382 tests, because not one of those tests drew anything: a control that never redrew, a tab strip that clipped mid-word, a form taller than its window with no way down, and colours that came from Material rather than the stylesheet. One regression test per class, and the spec's acceptance criterion is met rather than assumed -- each fault was put back deliberately and the matching test watched to fail. The CI had never run the suite at all; it does now, headless. What that took was not Xvfb: skiko's native library links against libGL and only has to be loadable, since the drawing tests render in software. Without the package the whole Compose half of the suite dies with a message that reads like a missing display. Found by running the job under act rather than on GitHub. The six tests that open a real window skip headless by their own guard. The summary step counts from the result XML and fails on failures there, because this project's rule is never to infer a green suite from an exit code. * Make the colours adjustable per operator profile Six colour roles per design, per profile: surface, window surface, field interior, text, accent and separator line. A change applies at once in every open window and survives a restart once the settings are saved, like any other preference. Three sources, later wins role by role: the shipped stylesheet from the classpath, then the profile's own stylesheet file if there is one, then the overrides stored in the profile's preferences. resolvePalette is a pure function and reports where every role's colour came from, which the tab shows per field -- with two sources able to decide one colour, that is the only thing keeping "why is this colour what it is" answerable, and the spec calls it mandatory rather than decorative. Four things this had to get right, each learned the hard way and each pinned: A role is a selector and a property, not a property alone. Three of the six are stated outside .root -- text on .label, the separator on .separator *.line -- and -fx-background-color alone appears a dozen times in the evening sheet. Measured: the shipped daylight sheet states no colour at all, the evening sheet states five and implies the sixth. Kst4ContestTheme reads the palette from the store's state and not from remember. That read is what makes a change repaint every open window; remember(darkMode) held the palette until somebody toggled day/evening, so a change reached nothing. A derived colour follows its source's value, never its provenance. The root profile's own stylesheet is the one copyResourceIfRequired writes at every startup -- the shipped sheet itself -- so layer 2 declares the accent on every existing installation with nobody having chosen anything. Keying textAccent on "does this come from a file" repainted the evening accent from green to blue on upgrade and made "reset to shipped" disagree with "discard my changes". The contrast guard measures where colours are actually drawn, read off Theme.kt's Material mapping rather than off the role names: background and surface are both the window surface, and primary is textAccent, not accent. It reports a pair only when it is both under WCAG AA and worse than the shipped sheet -- the shipped sheets have three pairs under 4.5 themselves, so an absolute floor would warn on an untouched client and teach the operator to ignore warnings. The way back out of an unreadable palette is deliberately overbuilt, because it is the one failure that locks itself in. "Reset to the shipped colours" takes the shipped palette as a required parameter and reads no composition local, so there is no path by which it could be drawn in the colours it exists to undo; it looks out of place under a customised palette, and that is what makes it findable. Ctrl+Z, Ctrl+D and Ctrl+R reach the three ways back even with the caret in a colour field. A mistyped colour is refused and the field snaps back. The profile's stylesheet is the hand-editing route the copy under ~/.praktiKST has been promising since it was first written and never read. It is read now. A button writes the shipped template as a starting point and never replaces a file that is already there. An unreadable, truncated or non-CSS file does not prevent startup -- the role falls back to the shipped design. A sheet stating -fx-base and no -fx-background states the derived window surface too, the way JavaFX does, or the most natural hand edit would leave every window the shipped light grey. 101 new tests. All of it runs headless. * Document the adjustable colours, and record the design and the plan Both manuals get the Colours tab in full: the six roles, that a change applies at once but survives a restart only after Save settings, the three ways back with their keyboard shortcuts, what each provenance label means, and the readability notice that warns without refusing. Two things an operator would otherwise have to discover. The reset button is always drawn in the shipped colours and works when nothing else can be read -- the risk section of the design says plainly that a keyboard path only helps whoever knows it, so the manual is where this has to be written down. And the root profile already has both stylesheet files, because KST4Contest has been writing them at startup for years, so most of its roles report "from file" rather than "shipped" with identical values. PROJECT_CONTEXT.md records the decisions that outlive this stage: the three sources and their precedence, that a role is a selector and a property, that the theme must read the store's state rather than remember, where the contrast pairs come from, why the root profile's file layer always exists, and why the lifeline refuses the active palette. Also corrects its claim that CSS stays global -- a profile now owns its stylesheets. The design document and the implementation plan are kept as they were written, including the plan's own corrections where measuring the code contradicted it. * Speak the operator's language The interface is German or English, chosen per operator profile on the GUI tab, in force at once in every open window, and remembered across restarts. 376 texts in both languages. The texts are ordinary .properties files that nobody has to compile: a contributor copies the English one, translates the values, and opens a pull request. A third module -- build tooling that never ships -- turns them into Kotlin before anything compiles, which is what makes a mistyped key and a wrong argument count compile errors rather than things an operator discovers. It lives in the main build rather than buildSrc because buildSrc's tests do not run on `./gradlew build`, measured, and a generator whose tests never run is the exact failure it exists to prevent. Incompleteness is allowed and incorrectness is not. A missing key warns and falls back to English, so a partial contributed language can be submitted at all; an orphan key, a placeholder the translation drops, a duplicate key or an unreadable file fail the build with the generator's own message naming the file. The argument count always comes from the English base. German is held complete by a test because it ships; a contributed language is not. What is deliberately not translated is the harder half. Protocol frames and chat commands would break the connection or go unread; the beacon texts, auto answers, snippets and shortcuts go to other radio amateurs and sit in every operator's stored profile; the 273 println calls in core are diagnostics, and a German stack trace is worse for whoever reads the bug report; and QRA, QRG, QTF, LOS, Fresnel and wkd read the same in either language. Three tests guard the boundary by measuring behaviour rather than text: the protocol frames built under three locales, every preference default compared by reflection, and no translation value being a protocol command. The reflective one is the only one that covers what nobody thought of. One insight turned up three times. Anything built outside a composition freezes the language it was built in: the window title, the settings tab strip and every column header are all constructed once at startup -- the columns from Java -- so each now holds a function read when it is drawn. That also fixed something older and unrelated to language: the main window's title was a fixed "KST4Contest (Compose)" for the whole session, where the JavaFX window had carried the live connection line. It carries it again. A column's id is never translated. It is what the remembered widths and order are keyed on. * Document the two languages, and how to contribute a third Both manuals get the language picker in full: where it sits, that it applies per profile and takes effect at once in every open window, and -- at more length -- what is deliberately left alone and why. An operator who sees an English beacon text in a German client should be able to read that it is meant that way. The contribution route is written down in both, because plain text files are only useful if somebody knows they are there: copy, translate, submit; a partial file is welcome; the build reports mistakes by file name and writes a worksheet of what is still missing. PROJECT_CONTEXT records the decisions that outlive this stage -- the four kinds of text and the rule that the addressee decides, that core produces no display text, that incompleteness is allowed and incorrectness is not, that anything built outside a composition needs its text read inside one, and that a column id is never translated. CLAUDE.md said two modules; there are three, and the third never ships. It also states the German orthography now, which this session got wrong across a spec and two plans: ss after a short vowel, so muss and dass. * Remove the implementation plans now that every stage is executed Thirteen plans, all of them step-by-step instructions for work that is committed. A plan left behind reads to the next person like an open intention, and these describe a build that no longer exists -- the first still explains how to introduce Gradle. The specifications stay. They say why the architecture is what it is, which the code cannot, and three of them are still argued from. The live-findings note stays too: CLAUDE.md sends people to it, and its hardest lesson -- that a blocking wait on the AWT event thread deadlocks the interface while the build stays green -- is written down nowhere else. Its sweep script stays as well. The note argues explicitly that the script belongs beside the finding so the next reader can measure rather than believe, and removing it would contradict the reasoning it illustrates. Two references in the note and one in the JavaFX-removal spec pointed at plans and now say where the reasoning went instead. * Point the JavaFX-removal spec at where its plan's reasoning went * Remove the stray release-metadata patch from the working tree A 416-line patch file that was applied long ago and has sat in the repository root since. It predates this branch and stays in the shared history, where rewriting it would mean rewriting commits that are already on main and on origin. * Check the translation files in CI and say what they hold classes already runs the generator, so an orphan key, a dropped placeholder or a duplicate fails the compile job with the generator's own message naming the file -- verified by breaking strings_de.properties on purpose. A step summary counts each language against the base, so the author of a translation PR sees what they covered without reading the build log. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Refuse a translation key that would not form a Kotlin name The generator escaped every translation value but emitted the key verbatim as the member identifier, and identifierFor strips only . _ - -- so a key carrying a space, a brace, a quote or a newline from a \uXXXX escape broke out of val <name>: String get() = lookup(...) into an init block or property initializer that runs when Strings is instantiated. Translation files are the contribution surface that arrives by pull request, so this was a path from a merged .properties change to code in every client. The generated identifier is now held to letters-then-letters-and-digits before any source is written, alongside the existing orphan and collision refusals. Proven by replaying a file-writing payload against the built generator: it now throws and writes nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Port the rebased diagnostics and session logging onto the modules origin/main landed replayable session logging (MessageHistoryRecorder), file logging (ApplicationFileLogging) and a user-list refresh split on the old flat layout. The rebase carried the new files, but three things needed the new architecture: - ChatController.fireUserListUpdate() used javafx Platform; core is toolkit-free now, so it dispatches through uiDispatcher like every other fire method. - Two new tests were left in the old src/test/java; moved into core. - ScoreServiceRefreshTest mocked javafx Platform statically; it now injects the DirectUiDispatcher the no-arg constructor installs. The Leaflet map performance work was dropped with the HTML map it optimised. classes testClasses and test are green: 1069 tests, 0 failures, 3 skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Give the debug-to-file recording a home in the Compose settings origin/main added a checkbox to the old JavaFX settings that recorded the whole ON4KST session to file; the Compose redraw dropped the old settings UI, so the toggle had no control left even though the preference and its wiring survived the rebase. It returns to the message-handling tab: the state writes the preference and asks the application, through a new SettingsHost callback, to open or close the error-log handler and the history recorder in the order the old checkbox kept. The explanatory line and its German translation say that passwords are redacted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Fix Codex review findings on PR 89: station row key, map selection, sort after filter - Station row key now includes the chat category, so the same callsign in two categories no longer collides. - Map marker click and Reset view go through the central station selection. - Sorting now operates on the filtered rows, so filters stay effective. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the map drawing test off the network and the user's tile cache The test assumed no tile ever arrives, but it used the default TileFetcher, which reads the real disk cache and the OSM tile server. On CI a tile now and then landed before the frame was rendered and covered the background the 'unreachable tile source' test asserts on. An empty temporary cache and a source that always fails make the assumption hold by construction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1034 lines
62 KiB
Markdown
1034 lines
62 KiB
Markdown
# Configuration
|
||
|
||
> 🇬🇧 You are reading the English version | 🇩🇪 [Deutsche Version](de-Konfiguration)
|
||
|
||
After the first start, the **settings window** opens – this is the central starting point for all configuration. It is recommended to keep the settings window open during operation (e.g. to quickly toggle the beacon on and off).
|
||
|
||
> **Important**: Use **Save Settings** for functional settings which should remain in effect after the next start. KST4Contest saves layout changes such as window sizes, divider positions and table-column widths automatically. The shared file is `~/.praktiKST/preferences.xml` on Linux and macOS and `%USERPROFILE%\.praktiKST\preferences.xml` (or `C:\Users\<Username>\.praktiKST\preferences.xml`) on Windows.
|
||
|
||
---
|
||
|
||
## Station Settings
|
||
|
||

|
||
|
||
### Login and Chat Categories
|
||
|
||
Enter the one local login callsign and password used for the ON4KST chat. Also select the **primary chat category** (e.g. IARU Region 1 VHF/Microwave).
|
||
|
||
The **second chat** option (Multi-Channel Login) adds another category (e.g. UHF/SHF) to the same ON4KST TCP session through Single Sign-on. KST4Contest does not open a second TCP connection and does not use another local login callsign or password.
|
||
|
||
**Name in Chat 2** configures only the visible, category-specific name field for the second category. It is neither another login nor a message destination. The visible name field, message context, QRG and beacon remain separate for each category. **Opposite Station Multi-Callsign Login Tagging**, by contrast, refers exclusively to remote stations which appear in the chat under several complete visible callsign variants.
|
||
|
||
### Callsign and Locator
|
||
|
||
Enter your own callsign and Maidenhead locator (6 characters, e.g. `JN49IJ`). The locator is not part of authentication. ON4KST shares it between both categories in the one TCP session, and KST4Contest also uses it for distance and direction calculations.
|
||
|
||
### Active Bands
|
||
|
||
The **My station uses …** checkboxes define the bands available in the current local station setup. Supported choices are 50 MHz, 70 MHz, 144 MHz, 432 MHz, 1296 MHz, 2320 MHz, 3400 MHz, 5760 MHz and 10 GHz.
|
||
|
||
This selection controls more than the visible band columns. It is also used for:
|
||
|
||
- the per-band Worked and NOT-QRV filters,
|
||
- the NOT-QRV controls visible in the **Further Info** panel,
|
||
- the `a` and `B+` band-opportunity calculation,
|
||
- the **New bands** filter,
|
||
- the band-upgrade hint after a log entry, and
|
||
- band-specific priority and Reachability functions.
|
||
|
||
After a change, click **Save Settings** and restart KST4Contest. Band columns and several related controls are created while the user interface is being built and are therefore not added or removed completely during the current session.
|
||
|
||
### Antenna Beamwidth
|
||
|
||
Enter the complete horizontal beamwidth of the local antenna in degrees. KST4Contest applies half of this value to either side of the selected or derived antenna direction. A configured value of `70°` therefore produces a corridor of `±35°`.
|
||
|
||
The value is used for:
|
||
|
||
- the QTF filter in the user list;
|
||
- the display of the local antenna corridor; and
|
||
- the assumed beamwidth of a remote station when [deriving directional opportunities](en-Features#directional-opportunities-from-directed-messages).
|
||
|
||
The final use is deliberately an approximation. ON4KST transmits neither the antenna being used nor its beamwidth. KST4Contest therefore uses the local value as a practical assumption for the remote station.
|
||
|
||
Choose a realistic value for the actual station setup. A value which is too large produces many geometrical matches with little practical meaning. A value which is too small may hide useful directional opportunities.
|
||
|
||
### Default Maximum QRB
|
||
|
||
Enter the maximum distance in kilometres within which KST4Contest should consider directional opportunities. The relevant distance is between the local station and the sender of the directed message, not between sender and receiver.
|
||
|
||
If the sender is farther away, the situation is neither highlighted nor forwarded as an automatic directional opportunity to the local DX Cluster server, even if the calculated angle would match.
|
||
|
||
### Path Analysis and Link Budget
|
||
|
||
The station map uses several values from the **Station** tab to calculate the terrain profile and link budget for the selected remote station. Enter the local station data as realistically as possible. The remote-station values remain global assumptions unless more accurate information is available.
|
||
|
||
| Setting | Use |
|
||
|---|---|
|
||
| **Own antenna height AGL** | Height of the local antenna above the surrounding terrain in metres |
|
||
| **Own TX power W** | Local transmit power in watts |
|
||
| **Own ant. gain dBi** | Gain of the local antenna in dBi |
|
||
| **DX OM TX power W** | Assumed transmit power of the remote station in watts |
|
||
| **DX OM ant. gain dBi** | Assumed antenna gain of the remote station in dBi |
|
||
|
||
**AGL** means *Above Ground Level*. Do not enter the height above sea level. The terrain elevation at the local station already comes from the elevation profile; KST4Contest adds the configured antenna height to this value.
|
||
|
||
For the remote station, KST4Contest currently uses a fixed antenna height of 10 metres above the local terrain. Its transmit power and antenna gain come from the two **DX OM** fields. These values are deliberately assumptions: ON4KST provides neither the actual antenna height nor the complete station data of the remote operator.
|
||
|
||
Antenna gains must be entered in `dBi`. Add `2.15 dB` before entering a value specified in `dBd`:
|
||
|
||
```text
|
||
dBi = dBd + 2.15 dB
|
||
```
|
||
|
||
The current QTF, configured antenna beamwidth and default maximum QRB affect the map display. The bands enabled for the local station and the frequency derived for the remote station also affect the selection of the analysis frequency.
|
||
|
||
For the terrain profile, KST4Contest uses the antenna heights, elevation model and Earth curvature with a fixed effective Earth-radius factor of `k = 4/3`. The link budget additionally includes:
|
||
|
||
- distance and the current analysis frequency,
|
||
- transmit powers and antenna gains in both directions,
|
||
- frequency-dependent estimated feeder losses,
|
||
- free-space path loss, and
|
||
- a rough additional loss caused by the relevant obstruction in the terrain profile.
|
||
|
||
The calculation is performed in both directions. The weaker direction determines the common SSB or CW margin. Optimistic power or antenna values therefore improve the displayed result, but they do not improve the real radio path.
|
||
|
||
The results remain engineering estimates. Current propagation conditions, local obstructions, vegetation, buildings, interference and unknown station parameters can change the actual result considerably. Operation, frequency selection and the limits of the calculation are described under [Station Map and Path Analysis](en-Features#station-map-and-path-analysis-from-v141).
|
||
|
||
---
|
||
|
||
## Server Settings (from v1.31)
|
||
|
||
The connection details for the ON4KST chat server are shown at the top of the **Station** tab. They normally do not need to be changed.
|
||
|
||
| Setting | Meaning |
|
||
|---|---|
|
||
| **ON4KST server** | DNS name or IP address of the chat server; the software default is `www.on4kst.org` |
|
||
| **Port** | TCP port of the chat server; the default is `23001` |
|
||
|
||
`www.on4kst.info` may also remain in an existing, working configuration. There is no reason to change it merely because the displayed name differs from the software default, provided that the chat connection remains reliable.
|
||
|
||
These values apply only to the outgoing ON4KST chat connection. They do not change the local DX cluster server or any connection to AirScout, PSTRotator or logging software.
|
||
|
||
The port must be between `1` and `65535`. An invalid entry is rejected and replaced with the last valid value. An incorrect server name or port, on the other hand, prevents KST4Contest from connecting to the chat.
|
||
|
||
Changing either value does not alter an existing TCP connection. Disconnect and reconnect the chat, or restart KST4Contest. Then use **Save Settings** so that the values are retained for the next program start.
|
||
|
||
---
|
||
|
||
## Log Sync Settings
|
||
|
||
The **Log sync** tab selects the sources from which KST4Contest imports worked stations. The three input paths provide different levels of detail:
|
||
|
||

|
||
|
||
| Input path | Data used | Result in KST4Contest |
|
||
|---|---|---|
|
||
| **Simplelogfile** | Callsigns read from a selected file | global Worked status, but no band or locator information |
|
||
| **General QSO UDP listener** | QSO packets from UCXLog, QARTest, N1MM+ and DXLog.net | global and per-band Worked status plus worked grid square where both band and locator are transmitted |
|
||
| **Win-Test network listener** | native Win-Test network packets | global and per-band Worked status, locator information and, depending on the settings, QRG synchronisation and sked handover |
|
||
|
||
The file-based interpreter reads the selected text file once per minute using a fixed callsign pattern. Matches are normalised to base callsigns and set only the global Worked status for all active variants. It is mainly useful when the logging application provides no supported network interface. A callsign match alone contains neither a reliable band nor a locator, so use one of the network listeners wherever possible if per-band information is required.
|
||
|
||
If the selected file does not exist, KST4Contest creates it and displays its full path together with checks for initial setup and the next contest. The file itself is the durable source; Worked marks derived from it are not stored in SQLite and are not reset automatically for a new contest.
|
||
|
||
The general QSO UDP listener is the recommended interface for UCXLog, QARTest, N1MM+ and DXLog.net. QSO and `RadioInfo` packets use the same configurable UDP port; the default is `12060`. Separate options in **Log sync** and **TRX sync** determine whether the received QSO and frequency information is processed.
|
||
|
||
Win-Test uses its own network protocol and therefore has a separate listener. Its default port is `9871`. If this port is changed while the listener is enabled, KST4Contest restarts the Win-Test listener on the new port. After changing the shared UDP port `12060`, KST4Contest must instead be restarted completely.
|
||
|
||
All enabled input paths may be used in parallel and identical reports do not create separate Worked states. Network-derived Worked information is stored in the internal database. Simplelogfile marks remain runtime state derived from the selected file. Before using Simplelogfile, check whether the logging application already provides one of the supported network interfaces. KST4Contest must be running when a network QSO is transmitted unless the logging application can resend the existing log.
|
||
|
||
Configuration of the individual logging applications, band and locator handling, and the Win-Test sked handover are described under [Log Synchronisation](en-Log-Sync).
|
||
|
||
---
|
||
|
||
## TRX Sync Settings
|
||
|
||
TRX synchronisation imports the current frequency from the logging application and makes it available in KST4Contest as the local QRG of the first chat category. QSO and frequency synchronisation may use the same UDP receiver, but they remain separate functions: receiving a `RadioInfo` packet does not mark a station as worked, and receiving a QSO packet does not automatically change the local QRG.
|
||
|
||

|
||
|
||
### Available QRG Sources
|
||
|
||
| Source | Setting | Behaviour |
|
||
|---|---|---|
|
||
| **General RadioInfo listener** | `Update MYQRG from RadioInfo messages received on the shared log-sync port` | Processes compatible `RadioInfo` packets on the UDP port shared with QSO synchronisation. The default port is `12060`. |
|
||
| **Win-Test STATUS** | `Win-Test STATUS QRG Sync` | Processes the main or pass frequency from native Win-Test `STATUS` packets. The Win-Test listener uses its separately configured port, which defaults to `9871`. |
|
||
| **Manual entry** | Disable both automatic QRG sources | The local QRG can be entered manually in the main window. |
|
||
|
||
The general listener is intended for logging applications which transmit compatible `RadioInfo` packets. Depending on their individual configuration, this includes UCXLog, N1MM+, QARTest and DXLog.net. QSO and `RadioInfo` packets use the same port configured under **Log sync**, but separate options determine whether KST4Contest processes QSO information, TRX information or both packet types. An automatic QRG source must be enabled and actually supply valid packets; enabling it alone does not update `MYQRG`.
|
||
|
||
Restart KST4Contest after changing the shared UDP port. Changes to the two QRG-sync checkboxes take effect immediately.
|
||
|
||
### Which QRG Is Updated?
|
||
|
||
Both automatic sources update `MYQRG` only. This is the local QRG of the first or primary chat category.
|
||
|
||
If a second chat is enabled, its QRG remains independent. It is not derived from incoming TRX packets and is available through `SECONDQRG`. The first category can therefore follow the logging application's frequency automatically while a separate QRG is entered manually for the second category.
|
||
|
||
When at least one automatic QRG source is enabled and supplies a valid value, the first category's QRG field in the main window follows the received frequency. If the expected packets do not arrive, verify the interface before the contest. Manual entry is available when both the general RadioInfo listener and Win-Test STATUS synchronisation are disabled.
|
||
|
||
### Main or Pass Frequency from Win-Test
|
||
|
||
By default, KST4Contest uses the main frequency contained in the Win-Test `STATUS` packet.
|
||
|
||
Enable `Use pass frequency from Win-Test STATUS` to use the packet's pass frequency instead. This is useful, for example, when Win-Test maintains a different frequency during split operation and that is the frequency which should be announced in the chat.
|
||
|
||
If the packet does not contain a valid pass frequency, KST4Contest automatically falls back to the main frequency. A missing pass frequency therefore neither clears `MYQRG` nor replaces it with an obviously incorrect number.
|
||
|
||
Frequencies use a consistent KST4Contest display format, for example:
|
||
|
||
```text
|
||
50.300.00
|
||
144.300.00
|
||
1296.100.00
|
||
10368.100.00
|
||
```
|
||
|
||
The number of digits before the first dot is derived from the frequency. Microwave frequencies with four or five MHz digits are therefore formatted correctly as well.
|
||
|
||
### Selecting the Win-Test Station
|
||
|
||
Several stations in a Win-Test network may transmit `STATUS` packets at the same time. `Win-Test station name filter` selects the station which is allowed to update the local QRG in KST4Contest.
|
||
|
||
Example:
|
||
|
||
```text
|
||
STN1
|
||
```
|
||
|
||
The comparison is case-insensitive. If the field is empty, `STATUS` packets from every Win-Test station are accepted.
|
||
|
||
In a multi-operator setup, set the filter to the station name of the operating position which actually belongs to this KST4Contest instance. Otherwise, a packet from another position may replace the QRG currently being displayed.
|
||
|
||
### Using MYQRG and SECONDQRG
|
||
|
||
The synchronised QRG can be used in every text processed by the common KST4Contest variable resolver. This includes:
|
||
|
||
- the send field,
|
||
- shortcuts,
|
||
- snippets, and
|
||
- automatic beacons.
|
||
|
||
`MYQRG` contains the complete QRG of the first chat category. `MYQRGSHORT` uses only its first seven characters. `SECONDQRG` contains the separately entered QRG of the second chat category.
|
||
|
||
Examples:
|
||
|
||
```text
|
||
I am calling cq at MYQRG
|
||
cq on MYQRGSHORT
|
||
second chat qrg SECONDQRG
|
||
```
|
||
|
||
The values are inserted when the message text is resolved. If the logging application changes frequency between two beacon runs, the next message already uses the updated value.
|
||
|
||
The local QRG may also be used as a fallback when handing a sked over to Win-Test. This only happens if the QRG can be parsed and belongs to the band explicitly selected for the sked. See [Log Synchronisation](en-Log-Sync#handing-skeds-over-to-win-test) for details.
|
||
|
||
Further information about text variables: [Macros and Variables](en-Macros-and-Variables#variables).
|
||
|
||
### Multiple Loggers or Radios
|
||
|
||
Every enabled QRG source writes to the same `MYQRG` value. KST4Contest does not currently assign incoming `RadioInfo` or `STATUS` packets to a particular radio or chat category.
|
||
|
||
If the general RadioInfo listener and Win-Test synchronisation are enabled at the same time, the most recently processed packet therefore determines the displayed QRG. The same applies when several logging applications send frequency packets to one KST4Contest instance.
|
||
|
||
For a setup containing several radios:
|
||
|
||
- QSO packets may be received from several logging applications.
|
||
- Frequency packets should only be transmitted by the source which is intended to control `MYQRG`.
|
||
- A Win-Test network should additionally use the station-name filter.
|
||
- If two completely independent QRG synchronisations are required, two separate KST4Contest instances provide the clearer arrangement.
|
||
|
||
In other words, combining several Worked sources is useful. Combining several simultaneously transmitting frequency sources merely creates a contest over which packet arrived last.
|
||
|
||
Click **Save Settings** after completing the configuration.
|
||
|
||
---
|
||
|
||
## AirScout Settings
|
||
|
||
The **AirScout** tab configures the UDP connection between KST4Contest and AirScout. KST4Contest does not request a general aircraft feed. It submits the station paths which are currently relevant, while AirScout calculates the matching aircraft and returns the result to the requesting KST4Contest instance.
|
||
|
||
AirScout `0.9.9.5` or newer is required.
|
||
|
||
{ width=85% }
|
||
|
||
### UDP Connection Settings
|
||
|
||
| Setting | Default | Use |
|
||
|---|---:|---|
|
||
| **Enable AirScout UDP integration** | disabled | Enables AirScout requests and the processing of returned information |
|
||
| **AirScout server identifier** | `AS` | Logical name of the AirScout instance being addressed |
|
||
| **KST4Contest client identifier** | `KST` | Logical name of this KST4Contest instance |
|
||
| **AirScout UDP port** | `9872` | Shared UDP port for requests and responses |
|
||
| **Select AirScout frequency automatically per station** | enabled | Derives a suitable band and frequency from the current context of each remote station |
|
||
| **Forced AirScout band value** | `1440000` | Uses one fixed AirScout band value for every station when automatic selection is disabled |
|
||
|
||
When **Enable AirScout UDP integration** is disabled, KST4Contest neither sends AirScout requests nor processes incoming AirScout responses. The UDP receiver may remain bound so that the integration can be enabled again during the current connection.
|
||
|
||
KST4Contest sends AirScout packets to the broadcast address `255.255.255.255`. No separate destination IP address is therefore configured. AirScout and KST4Contest must be able to receive the same UDP broadcast; routers do not normally forward this type of broadcast into another network. If communication fails, check the UDP port, local firewall and network assignment first.
|
||
|
||
### Automatic Band Selection per Station
|
||
|
||
**Auto per station** is the recommended setting. Instead of using one fixed band value for every remote station, KST4Contest derives a suitable frequency from the available operating context.
|
||
|
||
The sources are evaluated in this order:
|
||
|
||
1. the most recently detected QRG of the remote station, provided that it is no more than 30 minutes old,
|
||
2. one unambiguous complete QRG in the name field of an active chat entry,
|
||
3. unambiguous band designators in the name field,
|
||
4. 432 MHz if the same station is active in both the VHF/UHF and Microwave categories and 432 MHz is enabled for the local station,
|
||
5. the lowest locally enabled band belonging to the supported chat category.
|
||
|
||
Active chat variants of the same base callsign are evaluated together. Entries such as `CALLSIGN`, `CALLSIGN-2` and `CALLSIGN-432` can therefore contribute to the same band decision while remaining separate chat members for message processing.
|
||
|
||
Only bands enabled under **My station uses …** are eligible for automatic selection. A manually assigned NOT-QRV mark excludes the corresponding band and takes precedence over automatically detected QRG or name information.
|
||
|
||
The 50/70 MHz, VHF/UHF, Microwave and EME/JT65 chat categories are supported. Other ON4KST categories do not participate in AirScout band resolution. If no sufficiently reliable frequency can be determined, KST4Contest omits the request for that station. An arbitrary fallback to 144 MHz would produce a syntactically complete packet, but not necessarily a useful calculation.
|
||
|
||
Automatic AirScout selection uses the same propagation-frequency resolver as the internal path analysis. Both functions therefore evaluate the station path from the same technical basis.
|
||
|
||
### Fixed AirScout Band
|
||
|
||
When **Auto per station** is disabled, KST4Contest uses the value entered under **Forced AirScout band value** for every station.
|
||
|
||
Enter the value in the unit used by the AirScout UDP interface:
|
||
|
||
| Band | AirScout value |
|
||
|---|---:|
|
||
| 50 MHz | `500000` |
|
||
| 70 MHz | `700000` |
|
||
| 144 MHz | `1440000` |
|
||
| 432 MHz | `4320000` |
|
||
| 1296 MHz | `12960000` |
|
||
| 2320 MHz | `23200000` |
|
||
| 3400 MHz | `34000000` |
|
||
| 5760 MHz | `57600000` |
|
||
| 10368 MHz | `103680000` |
|
||
| 24048 MHz | `240480000` |
|
||
|
||
In fixed mode, neither the remote station's recently detected QRG nor a band stated in its name is considered. This option is therefore mainly useful for a station setup which is clearly limited to one band, or for troubleshooting.
|
||
|
||
### Server and Client Identifiers
|
||
|
||
The identifiers belong to the AirScout protocol. They are not DNS names or IP addresses.
|
||
|
||
Outgoing requests contain the client identifier followed by the server identifier:
|
||
|
||
```text
|
||
"KST" "AS"
|
||
```
|
||
|
||
AirScout returns them in the opposite order:
|
||
|
||
```text
|
||
"AS" "KST"
|
||
```
|
||
|
||
KST4Contest processes a response only if both identifiers exactly match the current configuration. The comparison is case-sensitive.
|
||
|
||
Identifiers must not be empty and must not contain quotation marks or line breaks.
|
||
|
||
If several KST4Contest instances operate in the same network, assign a distinct client identifier to each one, for example:
|
||
|
||
```text
|
||
KST-144
|
||
KST-432
|
||
```
|
||
|
||
If several AirScout instances are present, use distinct server identifiers as well. This prevents a response intended for one operating position from being processed by another KST4Contest instance.
|
||
|
||
### Which Stations Are Requested?
|
||
|
||
KST4Contest starts the first periodical AirScout request approximately ten seconds after the chat connection has been established. Further requests follow every 60 seconds.
|
||
|
||
An active station is included only if:
|
||
|
||
- a usable callsign is available,
|
||
- a locator is available,
|
||
- its distance has been calculated,
|
||
- its distance is below the configured **Maximum QRB**, and
|
||
- a usable band can be determined.
|
||
|
||
Several active chat entries of the same base callsign do not create a separate identical path calculation for every suffix. The returned AirScout information is subsequently assigned to the corresponding active chat variants.
|
||
|
||
This selection does more than reduce network traffic. It also prevents AirScout from continuously calculating paths outside the intended working range of the local station.
|
||
|
||
### Applying Changed Settings
|
||
|
||
The following changes are used for new packets immediately after leaving the input field or changing the checkbox:
|
||
|
||
- enabling or disabling the AirScout integration,
|
||
- server identifier,
|
||
- client identifier,
|
||
- automatic or fixed band selection, and
|
||
- the forced band value.
|
||
|
||
After changing the UDP port, disconnect and reconnect the chat or restart KST4Contest. The existing UDP receiver otherwise remains bound to the previous port.
|
||
|
||
Click **Save Settings** afterwards to retain the configuration.
|
||
|
||
AirScout setup, aircraft display and the meaning of the returned AP information are described under [AirScout Integration](en-AirScout-Integration).
|
||
|
||
---
|
||
|
||
## Notification Settings
|
||
|
||

|
||
|
||
The three audio functions work independently:
|
||
|
||
1. **Simple sounds**: Plays short cues for new private messages, detected directional opportunities, sked reminders and `BAND+` hints.
|
||
2. **CW announcement**: Spells the sender's callsign in CW for a new private message.
|
||
3. **Phonetic announcement**: Speaks the sender's callsign phonetically for a new private message.
|
||
|
||
Each function can be enabled separately. CW and phonetic output can also be active at the same time.
|
||
|
||
PM-related audio output is triggered only by messages actually directed to the local login callsign. Messages shown additionally through PM Catching and messages added through QSO Monitoring remain silent.
|
||
|
||
### Fallback Band for Relative QRG Detection
|
||
|
||
The **Fallback band for relative QRG detection** dropdown selects the band used when a relative QRG cannot be assigned to a recent station-specific band context.
|
||
|
||
Only band prefixes supported by the frequency parser are available:
|
||
|
||
```text
|
||
50 MHz
|
||
70 MHz
|
||
144 MHz
|
||
432 MHz
|
||
1296 MHz
|
||
2320 MHz
|
||
3400 MHz
|
||
5760 MHz
|
||
10368 MHz (10G)
|
||
24048 MHz (24G)
|
||
```
|
||
|
||
The dropdown is neither a filter nor an override for complete frequencies. `432.088` is recognised as a frequency in the 432 MHz band regardless of the selection. The fallback is needed for relative values such as `.205`, `,205` or `qrg 205`.
|
||
|
||
Before using the fallback, KST4Contest checks the sender's recent band context. If a complete frequency has been detected for the same station during the previous 30 minutes, that band takes precedence. A fallback setting of `144 MHz` therefore still turns `.100` into `432.100 MHz` if the station mentioned `432.088` shortly before.
|
||
|
||
Although this setting is located in the Notification tab, it affects the general QRG parser. It therefore influences the QRG column, detected active bands, priority calculations, band-upgrade hints and other functions which use a known station frequency – not only DX cluster spots.
|
||
|
||
Further details, including numbers which are deliberately ignored, are described under [QRG Detection](en-Features#qrg-detection).
|
||
|
||
### Local DX Cluster Output
|
||
|
||
KST4Contest can forward detected directional opportunities to logging software as DX cluster spots. A frequency recognised in the chat can therefore appear directly in the logger's band map without being entered manually.
|
||
|
||
The **Enable the local DX Cluster server …** checkbox starts or stops the local TCP server. When KST4Contest is connected to the chat, the change takes effect immediately.
|
||
|
||
The following settings and controls belong to the local DX cluster output:
|
||
|
||
- **TCP port**: Port on which KST4Contest accepts connections from DX cluster clients. The default is `8000`. Changing the port while the server is running restarts it on the new port. The logger must then reconnect to that port.
|
||
- **Fallback band for relative QRG detection**: The global fallback band described above. The test spot uses `.300` on this band. Actual spots use the QRG detected for the respective sender.
|
||
- **Spotter callsign**: Callsign shown as the spotter in generated DX cluster entries. A callsign different from the contest callsign should be used. Some logging programs filter spots apparently sent by the local station or treat them differently from external spots.
|
||
- **Send test spot**: Sends the following entry to every currently connected DX cluster client:
|
||
|
||
```text
|
||
Spotted callsign: DO5AMF
|
||
Comment: DXC test: You donated $100!
|
||
Frequency: .300 on the selected fallback band
|
||
```
|
||
|
||
With `144 MHz` selected as the fallback band, the resulting frequency is approximately `144.300 MHz`.
|
||
|
||
All spots use a fixed, DXSpider-compatible 75-character payload line with a 30-character comment field. Longer comments are deliberately truncated at this protocol boundary; the DX callsign is not. A callsign longer than twelve characters causes the affected spot to be rejected and logged.
|
||
|
||
The comment is a deliberately retained Easter egg. It has no technical meaning and, despite being remarkably specific, does not initiate a payment. Its practical purpose is to make the test spot easy to identify in the logging software.
|
||
|
||
The test works only if
|
||
|
||
1. KST4Contest is connected to the ON4KST chat,
|
||
2. the local DX cluster server is enabled, and
|
||
3. at least one DX cluster client is connected to KST4Contest.
|
||
|
||
KST4Contest does not generate a spot for every frequency found in the chat. An actual spot is created only when a directed message between two stations indicates a relevant antenna direction for the local station and a usable frequency is known for the sender.
|
||
|
||
The complete derivation and logger setup are described under [Built-in DX Cluster Server](en-DX-Cluster-Server).
|
||
|
||
---
|
||
|
||
### Band Upgrade Hint after a Log Entry
|
||
|
||
After receiving a log entry from UCXLog or Win-Test, KST4Contest can check whether the station which has just been worked still offers another common and unworked band.
|
||
|
||
The check uses the same derivation as the `a` and `B+` display:
|
||
|
||
1. the bands enabled in the local station settings,
|
||
2. QRGs detected for the remote station during the previous 30 minutes,
|
||
3. explicit band designators in the name fields of its active chat entries,
|
||
4. stored per-band Worked marks, and
|
||
5. manually assigned NOT-QRV marks.
|
||
|
||
Active chat variants of the same normalised callsign are evaluated together. NOT-QRV takes precedence over an automatically detected QRG or band designator.
|
||
|
||
If at least one common and unworked band remains, the main window displays a blinking **BAND+** hint for approximately twelve seconds. The callsign and remaining bands are included in the button text; the tooltip contains the complete derivation. If general notification sounds are enabled, KST4Contest also plays a short sound.
|
||
|
||
The two options serve different purposes:
|
||
|
||
- **Blink + sound …** enables the hint after a matching log entry.
|
||
- **Priority boost …** additionally raises the score of stations which have already been worked on at least one band but still offer another common and unworked band.
|
||
|
||
The Priority Boost is only one factor in the complete calculation. Distance, antenna direction, recent activity, AirScout data, skeds and negative hints may still change the final order. Enabling the option therefore guarantees neither a particular score nor a particular position in the priority list.
|
||
|
||
The other score weights currently have no separate user-interface controls. Several existing settings nevertheless provide input data for the calculation, particularly the [active bands](#active-bands), [antenna beamwidth](#antenna-beamwidth), [default maximum QRB](#default-maximum-qrb) and [AirScout settings](#airscout-settings).
|
||
|
||
The complete calculation is described under [Priority Score and Priority List](en-Features#priority-score-and-priority-list-from-v140).
|
||
|
||
|
||
The hint requires a log-synchronisation source which provides band information. The file-based callsign interpreter sees callsigns only and cannot reliably identify the band of the QSO which has just been logged.
|
||
|
||
Further explanation: [Band Upgrade Hint after a Log Entry](en-Features#band-upgrade-hint-after-a-log-entry).
|
||
|
||
---
|
||
|
||
## Shortcut Settings
|
||
|
||

|
||
|
||
Each entry in the upper part of the **Shortcuts** tab creates one button above the message field in the main window. Pressing the button appends its configured text to the current contents of the send field.
|
||
|
||
If the shortcut contains a [variable](en-Macros-and-Variables#variables), it is replaced with its current value when the text is inserted. A shortcut such as
|
||
|
||
```text
|
||
pse call me at MYQRGSHORT
|
||
```
|
||
|
||
may therefore insert:
|
||
|
||
```text
|
||
pse call me at 144.388
|
||
```
|
||
|
||
The exact entries `MYQRG` and `SECONDQRG` are additionally highlighted as QRG buttons. They insert the current frequency of the primary or secondary chat category respectively.
|
||
|
||
The shortcut `/SETNAME MYQRG` is highlighted as well. When it is pressed, KST4Contest resolves `MYQRG` and inserts the complete server command into the send field. The command is not transmitted automatically and can still be checked before it is sent with `Enter` or **TX**.
|
||
|
||
|
||
The order of the table determines the order of the buttons in the main window. Manage the entries as follows:
|
||
|
||
1. **Add shortcut** creates a new entry at the beginning of the list and immediately opens it for editing.
|
||
2. Double-click an existing entry to edit it. Press `Enter` to accept the change.
|
||
3. To remove an entry, delete its complete contents and confirm with `Enter`.
|
||
4. Use **Move selected up** and **Move selected down** to change the position of the selected entry.
|
||
|
||
Changes appear in the main window immediately. Use **Save Settings** afterwards if they should remain available after the next program start.
|
||
|
||
---
|
||
|
||
## Snippet Settings
|
||
|
||
Snippets are longer text blocks intended primarily for messages to a selected station. They can be opened through:
|
||
|
||
- a right-click on a station in the user list;
|
||
- a right-click on a message in the public chat table;
|
||
- a right-click on a message in the PM table; or
|
||
- `Ctrl+1` through `Ctrl+0` for the first ten entries in the snippet list.
|
||
|
||
The keyboard mapping follows the order of the table:
|
||
|
||
| Key combination | Snippet |
|
||
|---|---:|
|
||
| `Ctrl+1` | first entry |
|
||
| `Ctrl+2` | second entry |
|
||
| … | … |
|
||
| `Ctrl+9` | ninth entry |
|
||
| `Ctrl+0` | tenth entry |
|
||
|
||
A snippet selected from a context menu is appended to the message already prepared in the send field. Selecting a station or message will normally have inserted the appropriate `/cq` destination first.
|
||
|
||
A keyboard shortcut behaves differently: it replaces the current contents of the send field with a complete directed message:
|
||
|
||
```text
|
||
/cq CALLSIGN snippet text
|
||
```
|
||
|
||
The complete visible callsign, including any suffix, is retained. Selecting `9A0BB-70` may therefore produce:
|
||
|
||
```text
|
||
/cq 9A0BB-70 pse ur qrg?
|
||
```
|
||
|
||
The selected station's chat category is retained for transmission. If no station is selected, or no snippet is assigned to the chosen key combination, nothing is inserted.
|
||
|
||
Variables are resolved when the snippet is inserted. Station-specific variables such as `QRZNAME`, `FIRSTAP` and `SECONDAP` refer to the currently selected station. The prepared message is not sent automatically and can still be checked or edited. Press `Enter` or **TX** to send it; `Esc` clears the send field.
|
||
|
||
The snippet list is edited in the same way as the shortcut list:
|
||
|
||
1. **Add new snippet** creates a new entry at the beginning of the list.
|
||
2. Double-click an existing entry to edit it.
|
||
3. Press `Enter` to accept the change.
|
||
4. Confirming an empty entry removes it.
|
||
5. **Move selected up** and **Move selected down** change both the displayed order and the assignment to `Ctrl+1` through `Ctrl+0`.
|
||
|
||
The context menus and keyboard mappings are updated immediately. Use **Save Settings** afterwards to store the modified list permanently.
|
||
|
||
The complete list of available placeholders and their limitations is described under [Macros and Variables](en-Macros-and-Variables).
|
||
|
||
---
|
||
|
||
## Beacon Settings
|
||
|
||

|
||
|
||
A beacon sends a public CQ message at regular intervals. It is intended for operating situations in which the local station calls CQ on a fixed frequency for an extended period. Other stations receive current QRG information without requiring the operator to enter the same message repeatedly.
|
||
|
||
KST4Contest uses one shared timer for both chat categories. Each category nevertheless has its own enable setting and message template:
|
||
|
||
- **Enable CQ beacon** enables the beacon for the respective category.
|
||
- **Beacon message** contains the public message for that category.
|
||
- **Shared beacon interval** sets the common interval used by both categories.
|
||
|
||
When both beacons are enabled, they are sent one after the other in their respective categories during the same timer run. The second beacon is only considered while the second category is enabled and fully synchronised in the same ON4KST session.
|
||
|
||
### Interval and timer behaviour
|
||
|
||
The interval is entered in whole minutes. The minimum permitted value is one minute.
|
||
|
||
After the chat connection has been established, KST4Contest performs the first beacon check after approximately ten seconds. The configured interval applies after that initial check.
|
||
|
||
Changing the interval while connected restarts the countdown with the new value. The change itself does not cause an immediate beacon message.
|
||
|
||
Both categories use the same timer. Separate intervals for the primary and secondary chat cannot be configured.
|
||
|
||
### Message text and variables
|
||
|
||
A beacon may use the [global variables](en-Macros-and-Variables#variables-in-the-beacon) which depend only on the local station:
|
||
|
||
- `MYQRG`
|
||
- `MYQRGSHORT`
|
||
- `SECONDQRG`
|
||
- `MYLOCATOR`
|
||
- `MYLOCATORSHORT`
|
||
- `MYCALL`
|
||
- `MYQTF`
|
||
|
||
A suitable message for the primary chat category is:
|
||
|
||
```text
|
||
calling cq at MYQRGSHORT, ant MYQTF deg, loc MYLOCATOR
|
||
```
|
||
|
||
Use `SECONDQRG` for the second chat if it operates on a different frequency:
|
||
|
||
```text
|
||
calling cq at SECONDQRG, ant MYQTF deg, loc MYLOCATOR
|
||
```
|
||
|
||
Variables are resolved again on every timer run. If the logging software changes the QRG stored in `MYQRG`, the next beacon can already contain the updated value. The message template does not have to be edited.
|
||
|
||
`MYQRG` and `MYQRGSHORT` always refer to the primary chat category. Enabling or selecting the second chat does not change this assignment.
|
||
|
||
Station-specific variables such as `QRZNAME`, `FIRSTAP` and `SECONDAP` require a selected remote station. A public beacon has no such destination, so these variables are not resolved in beacon messages.
|
||
|
||
### Message validation
|
||
|
||
KST4Contest validates both the configured template and the message which remains after all variables have been resolved.
|
||
|
||
The following restrictions apply:
|
||
|
||
- The final message must not be empty.
|
||
- It must not exceed 120 characters.
|
||
- The protocol separator `|` is not permitted.
|
||
- Line breaks are not permitted.
|
||
|
||
An invalid entry is not accepted as the new beacon configuration. If a template becomes invalid only after resolving its variables, for example because the resulting text exceeds 120 characters, that beacon run is skipped.
|
||
|
||
A template which consists only of a temporarily empty global variable may still be stored. This can happen during startup before the first QRG has been received from the logger. KST4Contest does not send an empty message while the variable has no usable value.
|
||
|
||
### When should the beacon be disabled?
|
||
|
||
The beacon is useful only while its QRG matches the actual operation. Leaving it enabled while searching the band or changing frequencies frequently may cause other stations to look for the local station on an obsolete frequency.
|
||
|
||
In plain terms: the beacon saves work while calling CQ on a fixed QRG. It should be disabled while moving around the band.
|
||
|
||
Changes take effect during the current connection. Use **Save Settings** afterwards to retain the enable settings, message templates and interval for the next program start.
|
||
|
||
---
|
||
|
||
## Messagehandling Settings (from v1.25)
|
||
|
||

|
||
|
||
The most important use of the general automatic reply concerns stations which are logged into the ON4KST chat but are not taking part in the current contest. During larger contests, sked requests are sometimes sent to many logged-in stations without first checking whether they are participating. Without an automatic reply, the recipients would have to enter the same refusal repeatedly.
|
||
|
||
KST4Contest can answer these requests with a predefined message. A separate function provides the local QRG when a private message contains a recognised frequency request. Both functions can be enabled independently.
|
||
|
||
### General automatic reply
|
||
|
||
**Enable automatic reply to all private messages** answers incoming private messages with the text entered in the adjacent field. One common text is used for both chat categories. The configured capitalisation is preserved.
|
||
|
||
A suitable message is:
|
||
|
||
```text
|
||
Sri, I am not taking part in this contest. No skeds.
|
||
```
|
||
|
||
Do not add the `[KST4C Automsg]` prefix to the configured text. KST4Contest inserts it automatically.
|
||
|
||
The message received by the remote station may therefore be:
|
||
|
||
```text
|
||
[KST4C Automsg] Sri, I am not taking part in this contest. No skeds.
|
||
```
|
||
|
||
The incoming private message remains visible. The function neither blocks nor discards the request; it merely avoids entering the same answer repeatedly.
|
||
|
||
The reply is addressed to the sender's complete callsign, including any visible suffix, and sent through the chat category in which the private message was received. This distinction matters when two categories are connected at the same time: a request received through the microwave chat must not be answered accidentally through the VHF/UHF chat.
|
||
|
||
An empty or whitespace-only answer does not produce an automatic message. A configured text containing the protocol separator `|` or a line break is rejected as well.
|
||
|
||
### Automatic QRG reply
|
||
|
||
**Enable automatic QRG replies** reacts to common QRG requests. Matching is case-insensitive and looks for the following text fragments:
|
||
|
||
```text
|
||
ur qrg?
|
||
your qrg?
|
||
qrg?
|
||
freq?
|
||
pse qrg
|
||
```
|
||
|
||
The answer contains only the QRG belonging to the category in which the request was received:
|
||
|
||
| Incoming private message | QRG used for the reply |
|
||
|---|---|
|
||
| Primary category | current QRG of the primary category |
|
||
| Second chat category | current QRG of the second category |
|
||
|
||
A possible reply is:
|
||
|
||
```text
|
||
[KST4C Automsg] QRG is: 144.300.00
|
||
```
|
||
|
||
The values come from the same QRG fields used by `MYQRG` and `SECONDQRG`. The primary QRG may be entered manually or updated through [TRX synchronisation](#trx-sync-settings). The second category uses the value configured or entered for that category.
|
||
|
||
If no QRG is available for the incoming category, KST4Contest does not send an incomplete reply. A message containing `QRG is:` without a frequency would technically answer the request while providing no useful information. It is therefore rejected before reaching the transmit queue.
|
||
|
||
When both automatic-reply functions are enabled, the QRG reply takes precedence. A recognised QRG request does not additionally produce the general reply. If the required QRG is missing, KST4Contest does not fall back to the general answer.
|
||
|
||
### Debug and contest history
|
||
|
||
**Enable debug mode to file** is enabled by default and takes effect without restarting the application. The setting controls two separate files in the `.praktiKST` directory of the user profile:
|
||
|
||
- `kst4contest-errors.log` includes additional `INFO` and `FINE` diagnostics while debug mode is enabled. Warnings, errors and exceptions are written regardless of this setting.
|
||
- `Messagehistory.raw` records the complete ON4KST traffic of the current program session. It contains RX and TX traffic, including chat, private-message, user, status, control and keepalive frames.
|
||
|
||
On Windows, the history is stored at `C:\Users\<YourName>\.praktiKST\Messagehistory.raw`; on Linux and macOS it is stored at `~/.praktiKST/Messagehistory.raw`.
|
||
|
||
Each line contains exactly one event:
|
||
|
||
```text
|
||
UTC<TAB>RX|TX<TAB>RAW_FRAME
|
||
```
|
||
|
||
The UTC timestamp includes milliseconds. The third field is preserved unchanged except that the TCP line ending is not stored. Login frames remain recognisable for later analysis, but the password is replaced with `<REDACTED>`.
|
||
|
||
When recording is initialised for a new program session, an existing non-empty `Messagehistory.raw` is archived as `Messagehistory-YYYYMMDD-HHMMSSZ.raw`. Reconnects and repeated enabling during the same program session do not create another archive. Disabling the setting stops recording immediately; enabling it again appends to the current file.
|
||
|
||
The history is intended as a machine-readable basis for future replay and simulation tools. It contains the complete contest/session traffic and will normally include personal chat and station data. Inspect and handle the file accordingly before sharing it.
|
||
|
||
The existing `client_settings_window_messagehandling.png` screenshot does not yet show the new checkbox and should be replaced during the next screenshot update.
|
||
|
||
### Protection against repeated replies
|
||
|
||
Every automatically generated reply contains the fixed prefix:
|
||
|
||
```text
|
||
[KST4C Automsg]
|
||
```
|
||
|
||
The general and QRG-specific functions ignore messages which already contain this prefix. This prevents two clients with automatic replies enabled from answering each other indefinitely.
|
||
|
||
A common two-minute cooldown additionally applies to both reply types. The cooldown is tracked separately for each complete callsign and chat category.
|
||
|
||
This means:
|
||
|
||
- `CALLSIGN-2` and `CALLSIGN-70` have separate cooldowns.
|
||
- The same complete callsign can still receive an independent reply in another chat category.
|
||
- A general reply also suppresses a QRG reply to the same callsign in the same category for two minutes.
|
||
- A QRG reply likewise suppresses the general reply.
|
||
|
||
The cooldown starts only after KST4Contest has produced a complete, locally valid message and placed it in the transmit queue. A missing QRG, an empty general reply or a message rejected because of invalid characters does not start the cooldown. Once the missing information has been corrected, a valid reply can therefore be generated immediately.
|
||
|
||
> **Note**: The configured text should describe the actual operating status clearly. If the station is only observing the contest and does not accept skeds, say exactly that. A vague automatic message is likely to produce another question – which is precisely the work this function is intended to avoid.
|
||
|
||
Changes take effect during the current connection. Use **Save Settings** afterwards to retain the enable settings and general reply text for the next program start.
|
||
|
||
Further background: [Automatic Replies to Private Messages](en-Features#automatic-replies-to-private-messages-from-v125).
|
||
|
||
---
|
||
|
||
|
||
## Win-Test Network Listener (from v1.31)
|
||
|
||
The Win-Test network listener processes the native Win-Test UDP protocol. It is independent of the general QSO UDP listener on port `12060` and has three separate tasks:
|
||
|
||
- processing QSOs including band and locator information,
|
||
- processing STATUS packets for the local QRG, and
|
||
- handing skeds over to the Win-Test network.
|
||
|
||
### Log sync settings
|
||
|
||
| Setting | Function |
|
||
|---|---|
|
||
| **Receive Win-Test network based UDP log messages** | Enables the Win-Test network listener. When the listener is enabled, pressing **Create sked** also attempts the Win-Test handover. |
|
||
| **UDP-Port for Win-Test listener** | Port used by the Win-Test network. The default is `9871`. The same port is used for the sked handover. |
|
||
| **KST station name in Win-Test network (src of SKED packets)** | Station name used by KST4Contest when sending sked packets. A unique name should be used in a network containing several clients. |
|
||
| **Win-Test network broadcast address** | Destination address for outgoing Win-Test network packets. In a local network, the address must be reachable by the Win-Test computer. |
|
||
|
||
The broadcast address is configurable because `255.255.255.255` is not forwarded reliably through every station network or network interface. In a multi-computer setup, the directed broadcast address belonging to the station network may be required instead.
|
||
|
||
### TRX sync settings
|
||
|
||
| Setting | Function |
|
||
|---|---|
|
||
| **Win-Test STATUS QRG Sync** | Takes the current frequency from Win-Test STATUS packets and uses it as the local QRG. |
|
||
| **Use pass frequency from Win-Test STATUS** | Uses the transmitted pass frequency instead of the normal TRX QRG. |
|
||
| **Win-Test station name filter** | Only processes STATUS packets from the specified Win-Test station. An empty field accepts every station name. |
|
||
|
||
The station filter is particularly useful when several Win-Test clients are active. Without a filter, the most recently received STATUS packet from another operating position can overwrite the local QRG in KST4Contest.
|
||
|
||
### Sked handover
|
||
|
||
There is no separate internal sked mode for the Win-Test handover. When the listener is enabled, **Create sked** attempts the Win-Test transfer in addition to creating the internal sked.
|
||
|
||
KST4Contest only sends an `ADDSKED` packet when it can determine a QRG which belongs to the explicitly selected band. If no matching QRG is available, the internal sked remains intact and the Win-Test handover is omitted.
|
||
|
||
`SSB` or `CW` is selected directly in the Further Info section when the sked is created. No automatic mode inference is used.
|
||
|
||
Click **Save Settings** after making changes so that the port, station name, broadcast address and TRX options are restored at the next start.
|
||
|
||
Data handling and QRG selection: [Log Synchronisation – Win-Test](en-Log-Sync#win-test)
|
||
|
||
---
|
||
|
||
## PSTRotator Settings (from v1.31, fully configurable from v1.40)
|
||
|
||
KST4Contest can set an antenna direction through the PSTRotator UDP interface and use the current position reported by PSTRotator as the local QTF.
|
||
|
||
The settings are located in the **Station** tab:
|
||
|
||
| Setting | Default | Purpose |
|
||
|---|---:|---|
|
||
| **Enable PSTRotator** | disabled | Starts UDP communication with PSTRotator |
|
||
| **PSTRotator host** | `127.0.0.1` | Hostname or IP address of the computer running PSTRotator |
|
||
| **PSTRotator UDP port** | `12000` | UDP port on which PSTRotator receives control commands |
|
||
|
||
When both applications run on the same computer, `127.0.0.1` is normally the clearest setting. If PSTRotator runs on another computer in the station network, enter its reachable IP address or DNS name.
|
||
|
||
The port must be between `1` and `65534`. Port `65535` cannot be used because PSTRotator reports its position on the following port.
|
||
|
||
### Preparing PSTRotator
|
||
|
||
Configure the same UDP port under **Communication → UDP Control Port** in PSTRotator and enable **UDP Control**.
|
||
|
||
The default configuration uses the following pair:
|
||
|
||
| Direction | UDP port |
|
||
|---|---:|
|
||
| KST4Contest → PSTRotator | `12000` |
|
||
| PSTRotator → KST4Contest | `12001` |
|
||
|
||
KST4Contest binds the return port automatically. It is not configured separately.
|
||
|
||
When the programs run on different computers, the local firewalls and station network must permit UDP traffic in both directions. KST4Contest cannot receive position reports if another program already occupies the return port.
|
||
|
||
The complete UDP protocol is documented in the [PSTRotatorAz User Manual](https://www.qsl.net/yo3dmu/ANT/PstRotatorAz%20User%20Manual.pdf).
|
||
|
||
### Updating the local QTF
|
||
|
||
KST4Contest asks PSTRotator for the current azimuth and operating mode every two seconds. The reported azimuth becomes `actualQTF`.
|
||
|
||
While PSTRotator integration is enabled, the QTF field in the main window is therefore read-only. It displays the most recent position reported by PSTRotator.
|
||
|
||
This QTF is used by:
|
||
|
||
- the direction filter;
|
||
- the derivation of direction opportunities;
|
||
- the Priority Score;
|
||
- the antenna sector on the station map;
|
||
- the AP and sked timeline; and
|
||
- the `MYQTF` variable.
|
||
|
||
A received rotator position is therefore more than a displayed value. It changes several functions which depend on the current antenna direction.
|
||
|
||
The current integration uses azimuth only. Elevation control and complete azimuth/elevation tracking are outside its present scope.
|
||
|
||
### Applying changed settings
|
||
|
||
The enable setting, host and port are evaluated when the rotator connection is started. After changing them, disconnect and reconnect the ON4KST session or restart KST4Contest.
|
||
|
||
Use **Save Settings** afterwards so that the values are restored at the next program start.
|
||
|
||
---
|
||
|
||
## Sniffer Settings (from v1.31)
|
||
|
||
QSO monitoring is intended for stations whose communication should remain visible during busy chat activity. This may be a rare station, a DXpedition or another station in the same contest team whose sked arrangements should not disappear in the general message traffic.
|
||
|
||
The callsign list is maintained under **QSO monitoring** in the **Notification** tab.
|
||
|
||
For every monitored base callsign, KST4Contest additionally shows messages in the PM table when a variant of that callsign is either the sender or the receiver. Both connected chat categories are included.
|
||
|
||
The list intentionally uses the normalised base callsign. The following entries therefore produce the same monitoring entry:
|
||
|
||
```text
|
||
DN9APW
|
||
DN9APW-2
|
||
DN9APW-70
|
||
DN9APW-144
|
||
```
|
||
|
||
In every case, KST4Contest stores and displays:
|
||
|
||
```text
|
||
DN9APW
|
||
```
|
||
|
||
The different KST suffixes of one station do not have to be entered separately. A later message sent by `DN9APW-2` or addressed to `DN9APW-70` is covered by the same entry.
|
||
|
||
This aggregation applies to QSO monitoring only. Active ChatMember objects, complete message destinations and chat categories remain separate. A message addressed to `DN9APW-70` is therefore not redirected to `DN9APW-2`.
|
||
|
||
A monitored message is marked in the PM table using the complete visible callsigns of its sender and receiver:
|
||
|
||
```text
|
||
Sniffed: (DN9APW-2 > DL0ABC-70) Message text
|
||
```
|
||
|
||
The original message remains in its normal table. Monitoring changes neither its contents nor its routing.
|
||
|
||
A message is included only when the monitored station is actually its sender or receiver. Merely mentioning the callsign in the message text is not sufficient. Public messages sent by a monitored station are included as well; their receiver is displayed as `ALL`.
|
||
|
||
A message which is already addressed directly to the local callsign remains a normal private message and does not receive an additional `Sniffed:` marker.
|
||
|
||
Manage the list as follows:
|
||
|
||
1. Press **Add monitored callsign** to add an entry.
|
||
2. Double-click an existing entry to edit it and press `Enter` to apply the change.
|
||
3. To remove an entry, delete the complete cell contents and press `Enter`.
|
||
|
||
The entered value may contain a visible KST suffix or portable components. KST4Contest normalises it to the base callsign before storing it. Different variants of the same base callsign are therefore treated as duplicates.
|
||
|
||
Changes to the list take effect immediately. Press **Save Settings** afterwards to retain them. The base callsigns are stored in `preferences.xml` and restored at the next program start.
|
||
|
||
> Base-callsign monitoring across KST suffixes is included from v1.42 onwards.
|
||
|
||
Further background and the distinction from message routing: [QSO Sniffer](en-Features#qso-sniffer-from-v131).
|
||
|
||
---
|
||
|
||
## GUI Settings: Band-Column Hints
|
||
|
||
Two optional additions to the band columns can be enabled or disabled in the **GUI** tab:
|
||
|
||
- **Show "o" in band columns …** displays an `o` if the four-character grid square has already been worked on the relevant band. Disabling the option does not delete any database records; it only hides the additional indicator in the band columns. `wkdany` is unaffected.
|
||
- **Show "a" in band columns …** distinguishes a completely new callsign from a band opportunity involving a callsign already worked elsewhere. When disabled, both cases are displayed as `B+`. The band-opportunity calculation itself remains unchanged.
|
||
|
||
Changes are reflected in the current user interface immediately. Click **Save Settings** afterwards if they should persist after the next start.
|
||
|
||

|
||
|
||
---
|
||
|
||
## Worked Station Database Settings
|
||
|
||
The internal SQLite database stores contest-related state independently of the logging application's database:
|
||
|
||
- the global Worked status of a callsign,
|
||
- Worked status per band,
|
||
- manually assigned NOT-QRV marks per band, and
|
||
- worked four-character grid squares per band.
|
||
|
||
Worked marks from the Simplelogfile interpreter are the exception. They are copied from the selected file into runtime state only and are not persisted in SQLite. The file is the durable source and has no automatic contest reset. A database reset does not change or empty it; callsigns contained in the file are marked as worked again during the next periodic evaluation.
|
||
|
||
The normalised callsign, without visible chat brackets or category formatting, is used as the key. This allows active variants of the same callsign to be evaluated consistently.
|
||
|
||
Worked and NOT-QRV information expires automatically three days after its most recent change. Stored grid squares expire three days after the corresponding log entry. A manual reset before every contest is therefore normally unnecessary.
|
||
|
||
The **Reset worked, NOT-QRV and grid data...** button removes every Worked mark, NOT-QRV mark and stored worked grid square. A confirmation dialog is displayed first. Known callsign rows remain in the database; only the contest-related state is reset.
|
||
|
||
A reset is useful when you deliberately want to start with an empty contest state or have imported test data. It is not intended as a daily maintenance step.
|
||
|
||
Display and derivation: [Worked Callsigns, New Bands and New Grid Squares](en-Features#worked-callsigns-new-bands-and-new-grid-squares).
|
||
|
||
---
|
||
|
||
## Operator Profiles (from v1.50)
|
||
|
||
Several operators sharing one computer need different callsigns, locators and layouts. An operator profile bundles exactly that: **every profile has its own `preferences.xml`, and therefore its own settings and its own window layout.**
|
||
|
||
### Where the profiles live
|
||
|
||
| Profile | Settings | Worked stations |
|
||
|---|---|---|
|
||
| **Default** | `~/.praktiKST/preferences.xml` | `~/.praktiKST/praktiKST.db` |
|
||
| additional profiles | `~/.praktiKST/profiles/<profile ID>/preferences.xml` | shared, or `~/.praktiKST/profiles/<profile ID>/praktiKST.db` |
|
||
|
||
On Windows the same files live below `%USERPROFILE%\.praktiKST\`.
|
||
|
||
Everything else stays shared: audio files, colour schemes, DEM and terrain packages, the terrain profile cache (`terrainprofilecache.db`), the error log and the version information.
|
||
|
||
The **Default** profile keeps using exactly the files an existing installation already has. **Upgrading to v1.50 moves, copies and rewrites nothing.** Anyone reinstalling an older KST4Contest release finds their configuration and their worked stations unchanged.
|
||
|
||
### Shared or own worked stations
|
||
|
||
When a profile is created you decide where its worked, NOT-QRV and grid data come from:
|
||
|
||
- **Own worked stations** (default): the profile gets its own, initially empty database. This is what two operators with different callsigns sharing a private computer want.
|
||
- **Common station database**: the profile uses `~/.praktiKST/praktiKST.db`, the same database as the **Default** profile. This is the **multi operator station** case: there is only one station log, so the worked state should be the same for every operator.
|
||
|
||
Switching between the two settings moves no data. Worked data already collected stays where it was created. The three day expiry and the reset button always act on the database of the currently active profile.
|
||
|
||
### Managing profiles
|
||
|
||
The **Profiles** tab in the settings window lists all profiles with their name, the kind of worked data they use and when they were last used.
|
||
|
||
- **New profile...** creates a profile. It starts **without callsign and password**; both are entered afterwards on the **Station** tab.
|
||
- **Duplicate...** copies the complete configuration of the selected profile - antenna, locator, layout, beacon, integrations - **except callsign and password**. Worked stations are never copied.
|
||
- **Rename...** changes the displayed name only. Folders and files are untouched.
|
||
- **Delete...** removes the profile folder permanently. The **Default** profile and the currently active profile cannot be deleted. For a profile using the common station database, that database is left untouched.
|
||
- **Change worked stations...** switches between the common and an own database.
|
||
- **Switch to selected profile...** changes the profile while the application is running.
|
||
|
||
### Choosing a profile at startup
|
||
|
||
- As long as only **one** profile exists, KST4Contest asks **nothing** at startup and starts exactly as before. No profile registry is created either; only creating the second profile writes `~/.praktiKST/profiles.xml`.
|
||
- From **two** profiles on, a small selection appears at startup. The last used profile is preselected, and **Enter** or a double click start immediately.
|
||
- The `--profile=<name>` argument skips the selection and starts the named profile directly. Both the profile ID and the displayed name are accepted, case insensitively. An unknown name produces a note and then the normal selection - startup is never refused.
|
||
|
||
### Switching profiles while running
|
||
|
||
**File > Switch operator profile...**, or the button on the **Profiles** tab, switches without restarting the program. After a confirmation the ON4KST connection is closed and the user interface is rebuilt with the settings and layout of the selected profile. The layout of the previous profile is saved first; settings not yet confirmed with **Save Settings** are lost.
|
||
|
||
Once more than one profile exists, the main window title also shows the profile name.
|
||
|
||
### A note about passwords
|
||
|
||
As before, the ON4KST password is stored in clear text in the `preferences.xml` of each profile. On a shared computer, anyone with access to the user account can read the passwords of all profiles. Profiles separate configuration; they are **not** an access control mechanism.
|
||
|
||
---
|
||
|
||
## Dark Mode (from v1.26)
|
||
|
||
Each operator profile sets its own startup colour scheme: on the **GUI** tab under **Design**, choose **Light mode** or **Dark mode**. The choice takes effect immediately and is stored in the profile's `preferences.xml` with **Save Settings**.
|
||
|
||
For a quick change during operation, use **Windows → Use dark mode design** and **Windows → Use default mode design**. This switch only lasts until the next start or profile switch; after that the setting on the **GUI** tab applies again.
|
||
|
||
---
|
||
|
||
## Saving Settings
|
||
|
||
**Save Settings** stores functional settings and the complete current layout. Changes to window sizes and positions, relevant dividers, managed table-column widths and the **Group nearby stations** map setting are also saved automatically after a short delay. Any pending layout update is written when the programme exits.
|
||
|
||
- Storage location: `~/.praktiKST/preferences.xml` on Linux and macOS and `%USERPROFILE%\.praktiKST\preferences.xml` (or `C:\Users\<Username>\.praktiKST\preferences.xml`) on Windows
|
||
- The automatic layout writer does not copy functional changes which have not yet been confirmed with **Save Settings**.
|
||
- Configuration version 6 adds optional column-width entries below `guiOptions`. Older `preferences.xml` files remain readable. Missing or invalid widths simply cause KST4Contest to calculate useful initial widths again.
|
||
- Configuration version 7 adds `GUIstationMapClusteringEnabled` below `guiOptions`. If the entry is missing or unusable, spatial map clustering remains enabled.
|
||
- Older programme versions ignore the additional XML entries. If an older version rewrites the complete file, column widths and the stored **Group nearby stations** choice may be lost.
|
||
- If you encounter problems: delete the configuration file → KST4Contest will create a new one with default values.
|