feat: added FlexRadio support (meters & basic functions)
This commit is contained in:
@@ -226,6 +226,115 @@ func (m *Manager) SendSpot(s SpotInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
// FlexTXState is the FlexRadio transmit/ATU state surfaced to the dedicated
|
||||
// FlexRadio control tab. Levels are 0-100. (Phase 1: controls + state pushed by
|
||||
// the radio over TCP; live meters arrive over a separate UDP stream later.)
|
||||
type FlexTXState struct {
|
||||
Available bool `json:"available"` // backend is Flex and handshaked
|
||||
Model string `json:"model,omitempty"`
|
||||
RFPower int `json:"rf_power"`
|
||||
TunePower int `json:"tune_power"`
|
||||
Tune bool `json:"tune"` // tune carrier active
|
||||
Transmitting bool `json:"transmitting"` // interlock state = TRANSMITTING
|
||||
VoxEnable bool `json:"vox_enable"`
|
||||
VoxLevel int `json:"vox_level"`
|
||||
VoxDelay int `json:"vox_delay"`
|
||||
ProcEnable bool `json:"proc_enable"`
|
||||
ProcLevel int `json:"proc_level"`
|
||||
Mon bool `json:"mon"`
|
||||
MonLevel int `json:"mon_level"`
|
||||
MicLevel int `json:"mic_level"`
|
||||
ATUStatus string `json:"atu_status,omitempty"`
|
||||
ATUMemories bool `json:"atu_memories"`
|
||||
// Active RX slice DSP controls.
|
||||
RXAvail bool `json:"rx_avail"` // an RX slice exists
|
||||
AGCMode string `json:"agc_mode,omitempty"`
|
||||
AGCThreshold int `json:"agc_threshold"`
|
||||
AudioLevel int `json:"audio_level"`
|
||||
NB bool `json:"nb"`
|
||||
NBLevel int `json:"nb_level"`
|
||||
NR bool `json:"nr"`
|
||||
NRLevel int `json:"nr_level"`
|
||||
ANF bool `json:"anf"`
|
||||
ANFLevel int `json:"anf_level"`
|
||||
// External amplifier (PowerGenius XL).
|
||||
AmpAvailable bool `json:"amp_available"`
|
||||
AmpModel string `json:"amp_model,omitempty"`
|
||||
AmpOperate bool `json:"amp_operate"`
|
||||
AmpFault string `json:"amp_fault,omitempty"`
|
||||
// Live meters streamed over UDP (S-meter, PWR, SWR, temp, voltage…).
|
||||
Meters []FlexMeter `json:"meters,omitempty"`
|
||||
}
|
||||
|
||||
// FlexMeter is one live meter value (already scaled to real units).
|
||||
type FlexMeter struct {
|
||||
ID int `json:"id"`
|
||||
Src string `json:"src,omitempty"` // SLC / TX- / RAD / AMP…
|
||||
Name string `json:"name,omitempty"` // FWDPWR, SWR, LEVEL, PATEMP…
|
||||
Unit string `json:"unit,omitempty"`
|
||||
Value float64 `json:"value"`
|
||||
Lo float64 `json:"lo"`
|
||||
Hi float64 `json:"hi"`
|
||||
}
|
||||
|
||||
// FlexController is an OPTIONAL backend capability (the FlexRadio backend): the
|
||||
// SmartSDR-style transmit controls. Backends that don't implement it are skipped
|
||||
// by the FlexRadio tab. FlexState() is mutex-guarded in the backend so it's safe
|
||||
// to read off the CAT goroutine; the setters are dispatched onto it via FlexDo.
|
||||
type FlexController interface {
|
||||
FlexState() FlexTXState
|
||||
SetRFPower(int) error
|
||||
SetTunePower(int) error
|
||||
SetTune(bool) error
|
||||
SetVOX(bool) error
|
||||
SetVOXLevel(int) error
|
||||
SetVOXDelay(int) error
|
||||
SetProcessor(bool) error
|
||||
SetProcessorLevel(int) error
|
||||
SetMon(bool) error
|
||||
SetMonLevel(int) error
|
||||
SetMic(int) error
|
||||
ATUStart() error
|
||||
ATUBypass() error
|
||||
SetATUMemories(bool) error
|
||||
// RX slice DSP controls (target the active receive slice).
|
||||
SetAGCMode(string) error
|
||||
SetAGCThreshold(int) error
|
||||
SetAudioLevel(int) error
|
||||
SetNB(bool) error
|
||||
SetNBLevel(int) error
|
||||
SetNR(bool) error
|
||||
SetNRLevel(int) error
|
||||
SetANF(bool) error
|
||||
SetANFLevel(int) error
|
||||
// External amplifier (PowerGenius XL) operate/standby.
|
||||
SetAmpOperate(bool) error
|
||||
}
|
||||
|
||||
// FlexState returns the current FlexRadio transmit state, or (zero, false) when
|
||||
// the active backend isn't a Flex. Safe to call from any goroutine.
|
||||
func (m *Manager) FlexState() (FlexTXState, bool) {
|
||||
m.mu.RLock()
|
||||
b := m.backend
|
||||
m.mu.RUnlock()
|
||||
if fc, ok := b.(FlexController); ok {
|
||||
return fc.FlexState(), true
|
||||
}
|
||||
return FlexTXState{}, false
|
||||
}
|
||||
|
||||
// FlexDo dispatches a FlexRadio control onto the CAT goroutine. Errors if the
|
||||
// active backend isn't a Flex.
|
||||
func (m *Manager) FlexDo(fn func(FlexController) error) error {
|
||||
return m.exec(func(b Backend) error {
|
||||
fc, ok := b.(FlexController)
|
||||
if !ok {
|
||||
return fmt.Errorf("active CAT backend is not a FlexRadio")
|
||||
}
|
||||
return fn(fc)
|
||||
})
|
||||
}
|
||||
|
||||
// exec marshals a backend operation onto the CAT goroutine. Returns the
|
||||
// operation's error or a "busy"/"not running" error if dispatch failed.
|
||||
func (m *Manager) exec(fn func(Backend) error) error {
|
||||
|
||||
Reference in New Issue
Block a user