fix(autocall): the QSO in progress outranks the ladder
Six faults from an evening on 60 m, all in the same family: the engine judging a station by what the log wants from it and forgetting what is already under way. - An exchange was abandoned mid-QSO. The reply lands in the same period the ladder is re-read, and that period was judged before the reply was taken into account, so a better-ranked caller took the slot from a station that had just come back to us. The answer is settled first now, and our own report counts as being inside the exchange too — which also protects a QSO the operator started by hand. - A station just picked started with misses against it. Its transmit slot was unknown until a second decode, and with the parity unknown every period counted, including the one spent transmitting to it. - The freed slot after "it is working somebody else" was thrown away: the period's decodes are in hand, so the next station is picked from them rather than fifteen seconds later. Never mid-over. - Auto-call is never armed from a stored setting — not at launch, not on a profile switch. It is the one feature that puts the station on the air by itself and OpsLog starts with Windows. - It says what it is waiting for: a wanted station in a QSO with somebody else now shows beside the Auto button instead of looking idle. - Switching profile left the previous logbook's verdicts on screen. The worked-index, chase-new and the frontend's cached verdicts are dropped when the logbook changes. FT decodes: distance column, a message addressed to you set whole in green (the station you are calling keeps a tint — most of what it sends goes to other people), badge order L / Wkd / WL, list cleared when the RIG changes band. Rotor: new world-map compass from EC1KD's design, with the Ultrabeam boom and second lobe restored and the compact form preserved; the classic dial is kept and Settings → Rotator chooses between them. Stop no longer flickers on a rotor standing still — movement was inferred from a degree, less than the jitter a controller reports at rest.
This commit is contained in:
+28
-8
@@ -195,8 +195,10 @@ type AutoCallStatus struct {
|
||||
// Only is the chase list, carried in the status so the field in the decodes
|
||||
// toolbar and the one in Preferences are never two versions of the truth:
|
||||
// whichever is typed into, both show it.
|
||||
Only string `json:"only"`
|
||||
Target string `json:"target"`
|
||||
Only string `json:"only"`
|
||||
Target string `json:"target"`
|
||||
// Waiting: what it would call if that station were not in a QSO.
|
||||
Waiting string `json:"waiting"`
|
||||
Calls int `json:"calls"`
|
||||
Max int `json:"max"`
|
||||
Misses int `json:"misses"`
|
||||
@@ -218,7 +220,7 @@ func (a *App) GetAutoCallStatus() AutoCallStatus {
|
||||
set := a.GetAutoCallSettings()
|
||||
return AutoCallStatus{
|
||||
Enabled: set.Enabled, Only: set.Only,
|
||||
Target: st.Target, Calls: st.Attempts, Max: st.Max,
|
||||
Target: st.Target, Waiting: st.Waiting, Calls: st.Attempts, Max: st.Max,
|
||||
Misses: st.Misses, MaxMiss: st.MaxMiss, Stopped: st.Stopped,
|
||||
Greylisted: a.autoCallEngine().Greylisted(),
|
||||
Reason: reason,
|
||||
@@ -588,16 +590,34 @@ func (a *App) autoCallWatched(call string) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// startAutoCall arms the engine at launch.
|
||||
// startAutoCall starts the engine's loop, with auto-call OFF.
|
||||
//
|
||||
// The stored "on" is honoured, and the engine starts with NO target: a program
|
||||
// that came up already calling a station chosen before the last shutdown is not
|
||||
// something an operator can be expected to anticipate.
|
||||
// It is never on from a stored value. This is the one setting in the program
|
||||
// that puts the station on the air by itself, and the operator who left it on
|
||||
// last night is not necessarily the one at the desk now — nor necessarily at
|
||||
// the desk at all: OpsLog starts with Windows, and a rig that powers up with it
|
||||
// would begin calling into an empty shack, on whatever band the radio happens
|
||||
// to be on, hours after anybody decided that was a good idea.
|
||||
//
|
||||
// Arming it is one click, and it is a click somebody has to make.
|
||||
func (a *App) startAutoCall() {
|
||||
a.applyAutoCall()
|
||||
a.disarmAutoCall("launch")
|
||||
go a.autoCallLoop()
|
||||
}
|
||||
|
||||
// disarmAutoCall switches auto-call off and writes that down.
|
||||
//
|
||||
// The setting is what the toolbar and the settings panel both read, so turning
|
||||
// the engine off without storing it would show a lit switch over a silent
|
||||
// transmitter — and the operator's next click, meaning "on", would send "off".
|
||||
func (a *App) disarmAutoCall(why string) {
|
||||
if a.settingOr(keyAutoCallOn, "0") == "1" {
|
||||
applog.Printf("autocall: off at %s — it is never armed from a stored setting", why)
|
||||
}
|
||||
a.setSetting(keyAutoCallOn, "0")
|
||||
a.applyAutoCall()
|
||||
}
|
||||
|
||||
func (a *App) autoCallLoop() {
|
||||
// A quarter of a second. The sweeper is what closes a period, so its tick is
|
||||
// part of the same budget as acQuiet: a two-second tick added up to two
|
||||
|
||||
Reference in New Issue
Block a user