A K3NG controller answered PuTTY perfectly and told OpsLog 'no reply to C'. The reason is not the protocol: the client opened and CLOSED the serial port for every single command, and an Arduino-based controller resets when its port is opened — DTR pulses the reset pin. OpsLog was rebooting it several times a second, and every command it sent landed in a bootloader. The port is opened once and held, per COM port, at package level: the callers build a fresh Client per poll, so the port has to outlive them, and a serial port is a single-owner resource in any case. A newly opened port is given two seconds to boot before the first command, bytes left from a previous exchange are drained rather than read as this command's answer, and a failed exchange drops the port so the next starts from a clean open instead of repeating the same silence. Reply parsing was already right for both flavours and now has the real strings to prove it, that controller's '+0140' among them.
35 lines
941 B
Go
35 lines
941 B
Go
package gs232
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// Real replies, as the controllers actually send them — a K3NG answering "C"
|
|
// with "+0140" and CR+LF among them (reported from a live controller).
|
|
func TestAzimuthReplies(t *testing.T) {
|
|
cases := []struct {
|
|
raw string
|
|
want int
|
|
}{
|
|
{"+0140\r\n", 140}, // GS-232A, K3NG firmware
|
|
{"+0000\r", 0}, // due north
|
|
{"+0359\r\n", 359}, // just short of it
|
|
{"AZ=140\r\n", 140}, // GS-232B flavour
|
|
{"AZ=140 EL=000\r\n", 140}, // GS-232B with elevation on the same line
|
|
{"\r\n+0075\r\n", 75}, // a leftover terminator ahead of the answer
|
|
}
|
|
for _, c := range cases {
|
|
m := azRe.FindStringSubmatch(strings.TrimSpace(c.raw))
|
|
if m == nil {
|
|
t.Errorf("no azimuth found in %q", c.raw)
|
|
continue
|
|
}
|
|
got, _ := strconv.Atoi(m[1])
|
|
if got%360 != c.want {
|
|
t.Errorf("%q parsed as %d, want %d", c.raw, got%360, c.want)
|
|
}
|
|
}
|
|
}
|