fix: Antenna Genius show only available antennas per band

This commit is contained in:
2026-07-09 15:52:04 +02:00
parent e487aa78f3
commit 5ae2bad549
5 changed files with 66 additions and 9 deletions
+21 -3
View File
@@ -32,9 +32,13 @@ const (
)
// Antenna is one configured antenna (index + name as stored on the device).
// Bands is the device's band bitmask for the antenna (which bands it covers);
// 0 = unknown/all. The UI uses it to show only band-appropriate antennas, like
// the native 4O3A app.
type Antenna struct {
Index int `json:"index"`
Name string `json:"name"`
Bands int `json:"bands"`
}
// Status is the snapshot the UI renders.
@@ -65,6 +69,8 @@ type Client struct {
statusMu sync.RWMutex
status Status
antennas map[int]string // index → name (rebuilt into status.Antennas)
antBands map[int]int // index → band bitmask (which bands the antenna covers)
antRawN int // one-shot: how many raw antenna lines we've logged
stop chan struct{}
running bool
@@ -80,6 +86,7 @@ func New(host string, port int, password string) *Client {
password: strings.TrimSpace(password),
stop: make(chan struct{}),
antennas: map[int]string{},
antBands: map[int]int{},
status: Status{Host: host},
}
}
@@ -356,13 +363,24 @@ func (c *Client) parseAntenna(msg string) {
// The device stores spaces as underscores in names.
name = strings.TrimSpace(strings.ReplaceAll(name, "_", " "))
}
// Band bitmask: which bands this antenna is configured for. The device sends
// it as "band=<mask>" (a bitmask). Kept so the UI can show only band-relevant
// antennas (like the native app). Log the first few raw antenna lines so the
// exact field name + bit values can be confirmed on real hardware.
bands := kvInt(msg, "band")
c.statusMu.Lock()
if c.antRawN < 8 {
c.antRawN++
applog.Printf("antgenius: antenna raw #%d: %q (parsed band mask=%d/0x%X)", c.antRawN, msg, bands, bands)
}
if name != "" && !isPlaceholderName(name) {
c.antennas[id] = name
c.antBands[id] = bands
} else {
delete(c.antennas, id) // unconfigured slot ("Antenna 4", etc.) → not shown
delete(c.antBands, id)
}
c.status.Antennas = sortedAntennas(c.antennas)
c.status.Antennas = sortedAntennas(c.antennas, c.antBands)
c.status.Connected = true
c.statusMu.Unlock()
}
@@ -431,10 +449,10 @@ func isPlaceholderName(name string) bool {
return err == nil
}
func sortedAntennas(m map[int]string) []Antenna {
func sortedAntennas(m map[int]string, bands map[int]int) []Antenna {
out := make([]Antenna, 0, len(m))
for idx, name := range m {
out = append(out, Antenna{Index: idx, Name: name})
out = append(out, Antenna{Index: idx, Name: name, Bands: bands[idx]})
}
sort.Slice(out, func(i, j int) bool { return out[i].Index < out[j].Index })
return out