fix(tci): send the spot colour as an unsigned ARGB integer
Expert Electronics' own document gives the command whole:
SPOT:RN6LHF,CW,7100000,16711680,ANY_TEXT;
16711680 is 0x00FF0000 — positive. This backend sent the same field as a SIGNED
32-bit value, from a third-party example: with the alpha byte set to FF for
opacity, 0xFFFFA500 becomes -22336, and a spot whose colour ExpertSDR cannot
read is dropped without a reply or an error.
Reported on ExpertSDR3 1.3, which speaks TCI 2.x — the protocol version was
never the problem, and my first reading of that report was wrong.
The first three spots are now logged verbatim: an ignored spot leaves no trace
whatsoever, so that line is the only evidence of what went out.
This commit is contained in:
+27
-6
@@ -33,6 +33,8 @@ type TCI struct {
|
||||
// What the server said it is, from its "protocol:" announcement.
|
||||
serverName string
|
||||
serverVersion string
|
||||
// How many spots have been logged verbatim (the first few only).
|
||||
spotsSent int
|
||||
|
||||
// OnSpotClick is called when the user clicks one of our spots on the TCI
|
||||
// panorama (callsign + freq), so the host can fill the entry form. Set before
|
||||
@@ -160,6 +162,9 @@ func (t *TCI) Connect() error {
|
||||
// only to a client that has subscribed. 200 ms is the rate the protocol's own
|
||||
// examples use — fast enough for a needle, slow enough not to flood a socket
|
||||
// that also carries audio.
|
||||
if t.spotsEnabled {
|
||||
debugLog.Printf("TCI: panorama spots are ON — spots will be sent to the radio")
|
||||
}
|
||||
_ = t.send("rx_sensors_enable:true,200;")
|
||||
_ = t.send("tx_sensors_enable:true,200;")
|
||||
if t.spotsEnabled {
|
||||
@@ -241,11 +246,19 @@ func (t *TCI) SendSpot(s SpotInfo) error {
|
||||
// other two matching what already works here.
|
||||
_ = t.send(fmt.Sprintf("spot_delete:%s;", call))
|
||||
}
|
||||
// TCI's SPOT command wants the colour as a signed 32-bit DECIMAL integer in
|
||||
// 0xAARRGGBB order — NOT a "0x…" hex string (e.g. "spot:UN7GK,cw,14025000,
|
||||
// -16776961,test;"). ExpertSDR silently drops a spot whose colour field it
|
||||
// can't parse as a number, which is why spots never showed on the panorama
|
||||
// while tuning (a separate command) still worked.
|
||||
// The colour is a DECIMAL ARGB integer, and an UNSIGNED one.
|
||||
//
|
||||
// Expert Electronics' own protocol document gives the whole command:
|
||||
//
|
||||
// SPOT:RN6LHF,CW,7100000,16711680,ANY_TEXT;
|
||||
//
|
||||
// 16711680 is 0x00FF0000 — positive, alpha zero. This backend was sending
|
||||
// the same number as a SIGNED 32-bit value, taken from a third-party
|
||||
// example: with the alpha byte set to FF for opacity, 0xFFFFA500 becomes
|
||||
// -22336, and a spot whose colour field ExpertSDR cannot read is dropped in
|
||||
// silence. Reported on ExpertSDR3 1.3 (which speaks TCI 2.x, so the version
|
||||
// was never the problem): everything else worked and the panorama stayed
|
||||
// empty.
|
||||
hex := strings.TrimPrefix(strings.TrimPrefix(strings.TrimSpace(s.Color), "#"), "0x")
|
||||
if hex == "" {
|
||||
hex = "FFFFA500" // opaque orange default
|
||||
@@ -266,7 +279,15 @@ func (t *TCI) SendSpot(s SpotInfo) error {
|
||||
}
|
||||
// Commas/semicolons would break TCI's comma-separated argument parsing.
|
||||
text := strings.NewReplacer(",", " ", ";", " ").Replace(s.Comment)
|
||||
return t.send(fmt.Sprintf("spot:%s,%s,%d,%d,%s;", call, mode, s.FreqHz, int32(argb), text))
|
||||
cmd := fmt.Sprintf("spot:%s,%s,%d,%d,%s;", call, mode, s.FreqHz, argb, text)
|
||||
// The first few, verbatim. A spot that the radio ignores leaves no trace at
|
||||
// all — no reply, no error — so the only evidence that OpsLog sent one, and
|
||||
// in what shape, is this line.
|
||||
if n := t.spotsSent; n < 3 {
|
||||
t.spotsSent = n + 1
|
||||
debugLog.Printf("TCI: sending spot #%d: %s", n+1, strings.TrimSuffix(cmd, ";"))
|
||||
}
|
||||
return t.send(cmd)
|
||||
}
|
||||
|
||||
// Disconnect closes the WebSocket; the reader goroutine then exits.
|
||||
|
||||
Reference in New Issue
Block a user