feat: relay auto-control by frequency / band (PstRotator-style)
Automatically switches the Station Control relay boards from the rig's current frequency / band. Each relay carries one rule: off (manual), a frequency window (ON inside [lo,hi] kHz, OFF outside), or a set of bands (ON on those bands, OFF elsewhere). Evaluated on every CAT frequency/band change; a relay is only switched when its desired state actually changed, so tuning within a range doesn't hammer the board. A cached atomic flag keeps the CAT hot path a no-op when the feature is off (important during FT8 slice churn). Saving re-applies from the live frequency so a changed rule takes effect immediately. New Settings → Hardware → Relay auto-control section: master enable plus a per-relay mode (Off / Frequency / Band) with kHz range inputs or band chips, per configured relay board. i18n EN + FR. Azimuth/Time modes (the other two PstRotator tabs) are left for later.
This commit is contained in:
@@ -484,6 +484,9 @@ type App struct {
|
||||
pttMu sync.Mutex
|
||||
udpLogMu sync.Mutex // serialises UDP auto-log so concurrent packets can't both pass the dedup check
|
||||
adifMonMu sync.Mutex // guards the ADIF-monitor config (file list + per-file read offsets)
|
||||
relayAutoMu sync.Mutex // serialises relay auto-control evaluation
|
||||
relayAutoLast map[string]bool // deviceID|relay → last applied on/off, so we only switch on a real change
|
||||
relayAutoOn atomic.Bool // cached "auto-control enabled" so the CAT hot path skips work when off
|
||||
pttPort serial.Port // open serial port while PTT (RTS/DTR) is asserted
|
||||
pttKeyedMethod string // "cat" | "rts" | "dtr" while keyed; "" when idle
|
||||
pttGen int64 // bumped on every key; a delayed unkey only fires if unchanged (guards against a stale release cutting a new transmission)
|
||||
@@ -810,6 +813,7 @@ func (a *App) startup(ctx context.Context) {
|
||||
a.qso = qso.NewRepo(logbookConn)
|
||||
go a.rebuildWorkedIndex() // in-memory worked-index for per-spot alert checks
|
||||
go a.adifMonitorLoop() // watch external ADIF files (fldigi, N1MM…) for new QSOs
|
||||
a.relayAutoOn.Store(a.GetRelayAuto().Enabled) // prime the relay auto-control hot-path flag
|
||||
|
||||
// cty.dat for offline DXCC / country resolution. Cached on disk; first
|
||||
// run downloads it from country-files.com in the background so startup
|
||||
@@ -895,6 +899,13 @@ func (a *App) startup(ctx context.Context) {
|
||||
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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user