From b818a2d94733492ec23602e1615dbde325babfa2 Mon Sep 17 00:00:00 2001 From: rouggy Date: Tue, 21 Jul 2026 01:09:13 +0200 Subject: [PATCH] fix: correct SPE status CSV field alignment (leading empty field shifts indices +1); decode band code; OPERATE/STANDBY now reflects real amp state --- internal/spe/spe.go | 66 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/internal/spe/spe.go b/internal/spe/spe.go index 814adef..3fb0012 100644 --- a/internal/spe/spe.go +++ b/internal/spe/spe.go @@ -279,26 +279,64 @@ func (c *Client) decodeCSV(payload string) { } c.status.Connected = true c.status.LastError = "" - c.status.Model = get(0) - c.status.Operate = get(1) == "O" - c.status.TX = get(2) == "T" - c.status.Input = get(4) - c.status.Band = get(5) - c.status.PowerLevel = get(8) - c.status.OutputW = pi(get(9)) - c.status.SWRATU = pf(get(10)) - c.status.SWRAnt = pf(get(11)) - c.status.VoltPA = pf(get(12)) - c.status.CurrPA = pf(get(13)) - c.status.TempC = pi(get(14)) - if w := get(17); w != "" && w != "N" { + // The real frame carries a leading empty field (it starts with a comma), so the + // 19 documented fields live at indices 1..19, not 0..18. Verified against a live + // 1.3K-FA: ",13K,S,R,A,1,05,1b,0r,M,0000, 0.00, 0.00, 1.3, 0.0, 26,000,000,N,N,". + c.status.Model = get(1) + c.status.Operate = get(2) == "O" // "O" = OPERATE, "S" = STANDBY + c.status.TX = get(3) == "T" // "T" = transmit, "R" = receive + c.status.Input = get(5) + c.status.Band = bandName(get(6)) + c.status.PowerLevel = get(9) + c.status.OutputW = pi(get(10)) + c.status.SWRATU = pf(get(11)) + c.status.SWRAnt = pf(get(12)) + c.status.VoltPA = pf(get(13)) + c.status.CurrPA = pf(get(14)) + c.status.TempC = pi(get(15)) + if w := get(18); w != "" && w != "N" { c.status.Warnings = w } else { c.status.Warnings = "" } - if a := get(18); a != "" && a != "N" { + if a := get(19); a != "" && a != "N" { c.status.Alarms = a } else { c.status.Alarms = "" } } + +// bandName maps the SPE 2-digit band index to a human band label, falling back to +// the raw code for anything unrecognised. +func bandName(code string) string { + switch strings.TrimSpace(code) { + case "00": + return "160m" + case "01": + return "80m" + case "02": + return "60m" + case "03": + return "40m" + case "04": + return "30m" + case "05": + return "20m" + case "06": + return "17m" + case "07": + return "15m" + case "08": + return "12m" + case "09": + return "10m" + case "10": + return "6m" + case "11": + return "4m" + case "": + return "" + default: + return code + } +}