Reported: OpsLog shows STANDBY on a PowerGenius XL that is operating, and
pressing the button 'puts it in Operate' — because it was already there.
The amplifier's status frame has no operate= field. The direct GSCP
client only looked for one, so Operate stayed at its zero value until the
operator pressed the button: at startup OpsLog was not reading the state
wrongly, it was not reading it at all.
The live state is in the frame under 'state', and the FlexRadio side of
this same amplifier has been reading it that way all along — anything but
STANDBY/OFF means the amp is in line, with IDLE meaning in line but not
keyed. The GSCP client now does the same when no operate= is present.
An unknown state leaves the flag alone rather than guessing: claiming
STANDBY on an amp that is in line is precisely the error being fixed, and
it invites the operator to switch on what is already on.
The amplifier PUSHES status frames ("S0|state=…") on the same socket it answers
commands on, and it pushes them constantly once in OPERATE - power, SWR and
temperature all move while transmitting.
command() read exactly one line and took whatever arrived first as its answer.
One pushed frame therefore put the stream permanently one reply behind: every
later command read the PREVIOUS command's answer, and eventually one waited out
the 3 s deadline, failed, and dropped the connection. Hence a fresh TCP
connection and a fresh authentication every few seconds in the log.
The stall in transmit is the same defect seen from the other side: command()
holds the connection mutex across that whole dead wait, so SetOperate and every
other control queued behind up to three seconds of nothing.
It only appeared remotely and in OPERATE because that is when there is anything
to push - on a LAN with an idle amplifier the race hardly ever opens. Which is
why it did not do this yesterday.
readReplyLocked now reads until the R<id>| that belongs to the command, feeding
every frame it passes to parse() on the way - a pushed status is fresher than
the one we were about to ask for, so nothing is wasted.
authLocked used the same one-line read and worked around this by re-sending the
whole handshake, which is visible in the log as "auth reply=S0|state=IDLE
(try 1)" followed by a second attempt. It goes through the same reader now.
Confirmed live: "setup fanmode=CONTEST" is accepted (reply code 0) while the
bare "fanmode=CONTEST" we switched to earlier is rejected (0x50000015), so the
fan mode snapped back and never changed on the amp. Restored the "setup " verb
and now check the reply code, returning an error if the amp rejects the set.
- PGXL: remote AUTH password; direct-link meter fallback (VITA-first) with
250 ms poll + peak-hold; fan mode uses bare "fanmode=" (was ignored).
- TCI: spot colour sent as decimal ARGB (ExpertSDR dropped the hex string);
spot click handled via CLICKED_ON_SPOT / RX_CLICKED_ON_SPOT to fill the entry.
- FlexRadio: clicking an OpsLog spot on the panadapter now applies the mode too.
- Filter presets: the trash icon deletes again (Radix pointer-down intercept).
- PTT hotkey: keys over CAT when a backend is active (was hijacked by a stale
Audio-tab RTS/DTR serial setting); AltGr keys allowed; presses logged.
- CW macro <LOGQSO>: logs after the preceding CW is sent, not on the first letter.