Compare commits
2
Commits
9c62bf0152
...
be66ac1e19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be66ac1e19 | ||
|
|
6aab4a6989 |
@@ -814,6 +814,33 @@ func (a *App) startup(ctx context.Context) {
|
|||||||
a.lookup = lookup.NewManager(a.cache)
|
a.lookup = lookup.NewManager(a.cache)
|
||||||
a.reloadLookupProviders()
|
a.reloadLookupProviders()
|
||||||
|
|
||||||
|
// CAT manager: emit pushes state to the frontend via Wails events, and
|
||||||
|
// forwards frequency/mode to any outbound UDP emitters (PstRotator, N1MM).
|
||||||
|
// Started HERE — before the (possibly slow, remote) MySQL logbook connect
|
||||||
|
// below — because the rig link only needs the local settings, and blocking it
|
||||||
|
// behind a 10–30s MySQL dial made the FlexRadio (and every CAT backend) take
|
||||||
|
// that long to come up at launch.
|
||||||
|
a.cat = cat.NewManager(func(s cat.RigState) {
|
||||||
|
// DIAGNOSTIC: the manager only fires this on a USER-relevant change, so a
|
||||||
|
// burst of these lines = the frontend is being re-rendered rapidly (the
|
||||||
|
// "screen flickers" symptom). Shows WHAT is churning — connection flap,
|
||||||
|
// or freq/split/mode oscillating between slices during FT8.
|
||||||
|
applog.Printf("cat:state → connected=%v freq=%d rx=%d split=%v mode=%s band=%s",
|
||||||
|
s.Connected, s.FreqHz, s.RxFreqHz, s.Split, s.Mode, s.Band)
|
||||||
|
if a.ctx != nil {
|
||||||
|
wruntime.EventsEmit(a.ctx, "cat:state", s)
|
||||||
|
}
|
||||||
|
a.emitRadioUDP(s)
|
||||||
|
// Drive station relays by the current frequency/band (PstRotator-style
|
||||||
|
// automatic control). Cheap cached-flag check keeps this a no-op when the
|
||||||
|
// feature is off; when on, run off this callback so a slow relay board never
|
||||||
|
// stalls rig-state processing.
|
||||||
|
if a.relayAutoOn.Load() {
|
||||||
|
go a.applyRelayAuto(s.FreqHz, s.Band)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
a.reloadCAT()
|
||||||
|
|
||||||
// The QSO logbook lives where the ACTIVE PROFILE points it: the local SQLite
|
// The QSO logbook lives where the ACTIVE PROFILE points it: the local SQLite
|
||||||
// file, or a per-profile shared MySQL database. Switching profiles switches
|
// file, or a per-profile shared MySQL database. Switching profiles switches
|
||||||
// the logbook (see switchLogbook). One-time: adopt any legacy config.json
|
// the logbook (see switchLogbook). One-time: adopt any legacy config.json
|
||||||
@@ -908,28 +935,6 @@ func (a *App) startup(ctx context.Context) {
|
|||||||
fmt.Printf("OpsLog: clublog cty.xml loaded — %d exceptions (%s)\n", n, d)
|
fmt.Printf("OpsLog: clublog cty.xml loaded — %d exceptions (%s)\n", n, d)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// CAT manager: emit pushes state to the frontend via Wails events, and
|
|
||||||
// forwards frequency/mode to any outbound UDP emitters (PstRotator, N1MM).
|
|
||||||
a.cat = cat.NewManager(func(s cat.RigState) {
|
|
||||||
// DIAGNOSTIC: the manager only fires this on a USER-relevant change, so a
|
|
||||||
// burst of these lines = the frontend is being re-rendered rapidly (the
|
|
||||||
// "screen flickers" symptom). Shows WHAT is churning — connection flap,
|
|
||||||
// or freq/split/mode oscillating between slices during FT8.
|
|
||||||
applog.Printf("cat:state → connected=%v freq=%d rx=%d split=%v mode=%s band=%s",
|
|
||||||
s.Connected, s.FreqHz, s.RxFreqHz, s.Split, s.Mode, s.Band)
|
|
||||||
if a.ctx != nil {
|
|
||||||
wruntime.EventsEmit(a.ctx, "cat:state", s)
|
|
||||||
}
|
|
||||||
a.emitRadioUDP(s)
|
|
||||||
// Drive station relays by the current frequency/band (PstRotator-style
|
|
||||||
// automatic control). Cheap cached-flag check keeps this a no-op when the
|
|
||||||
// feature is off; when on, run off this callback so a slow relay board never
|
|
||||||
// stalls rig-state processing.
|
|
||||||
if a.relayAutoOn.Load() {
|
|
||||||
go a.applyRelayAuto(s.FreqHz, s.Band)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
a.reloadCAT()
|
|
||||||
|
|
||||||
// POTA: background poller of api.pota.app so cluster spots can be tagged
|
// POTA: background poller of api.pota.app so cluster spots can be tagged
|
||||||
// when the DX station is currently activating a park. Best-effort.
|
// when the DX station is currently activating a park. Best-effort.
|
||||||
|
|||||||
+4
-13
@@ -2197,20 +2197,11 @@ export default function App() {
|
|||||||
while (autoCallMacroRef.current === i && gen === autoCallGenRef.current && wkActiveRef.current) {
|
while (autoCallMacroRef.current === i && gen === autoCallGenRef.current && wkActiveRef.current) {
|
||||||
const m = wkMacros[i];
|
const m = wkMacros[i];
|
||||||
if (!m) break;
|
if (!m) break;
|
||||||
|
// wkSend now WAITS for the CW to finish sending on its own (per-segment, all
|
||||||
|
// engines), so we must NOT re-wait the estimated duration here — doing both
|
||||||
|
// double-counted the send time and made the gap between calls far longer than
|
||||||
|
// configured (a 4 s gap became ~13 s). Just wait the configured gap.
|
||||||
await wkSend(m.text);
|
await wkSend(m.text);
|
||||||
// Wait for the message to finish before the gap+resend. The Icom keyer has
|
|
||||||
// no busy echo, so just wait the estimated send time. For the WinKeyer, cap
|
|
||||||
// the wait at the ESTIMATED send time (not the busy flag alone): over a
|
|
||||||
// remote/serial-over-IP link the "busy" status lags badly and stays stuck
|
|
||||||
// true for tens of seconds, which made the next CQ fire ~120s late.
|
|
||||||
if (cwSourceRef.current === 'icom' || cwSourceRef.current === 'flex') {
|
|
||||||
await sleep(Math.round(estimateCwMs(resolveCW(m.text), wkWpm)) + 300);
|
|
||||||
} else {
|
|
||||||
const capMs = Math.round(estimateCwMs(resolveCW(m.text), wkWpm) * 1.4) + 2500;
|
|
||||||
for (let k = 0; k < 20 && !wkBusyRef.current && gen === autoCallGenRef.current; k++) await sleep(50); // ≤1s to start
|
|
||||||
const deadline = Date.now() + capMs;
|
|
||||||
while (wkBusyRef.current && gen === autoCallGenRef.current && Date.now() < deadline) await sleep(50);
|
|
||||||
}
|
|
||||||
if (gen !== autoCallGenRef.current) break;
|
if (gen !== autoCallGenRef.current) break;
|
||||||
await sleep(Math.max(0, wkAutoCallSecsRef.current) * 1000); // the gap before the next call
|
await sleep(Math.max(0, wkAutoCallSecsRef.current) * 1000); // the gap before the next call
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user