fix(pgxl): read the amplifier's real state instead of assuming standby
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.
This commit is contained in:
@@ -159,6 +159,22 @@ func replyCode(reply string) string {
|
||||
return strings.TrimSpace(p[1])
|
||||
}
|
||||
|
||||
// operateFromState maps the amplifier's live state to "in line or not".
|
||||
//
|
||||
// Unknown states leave the flag alone rather than guessing: a state nobody has
|
||||
// seen is not evidence that the amp is standing by, and claiming STANDBY on an
|
||||
// amplifier that is in line is the error that matters here — it invites the
|
||||
// operator to "switch it on" and command the state it is already in.
|
||||
func operateFromState(state string) (operate, known bool) {
|
||||
switch strings.ToUpper(strings.TrimSpace(state)) {
|
||||
case "STANDBY", "OFF", "POWERED_OFF", "DISCONNECTED":
|
||||
return false, true
|
||||
case "OPERATE", "OPERATING", "IDLE", "RECEIVE", "RX", "TRANSMIT", "TRANSMIT_A", "TRANSMIT_B", "TX", "KEYED":
|
||||
return true, true
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
// SetOperate puts the amp in OPERATE (1) or STANDBY (0).
|
||||
func (c *Client) SetOperate(on bool) error {
|
||||
v := "0"
|
||||
@@ -349,6 +365,7 @@ func (c *Client) parse(resp string) {
|
||||
c.lastRaw = data
|
||||
applog.Printf("pgxl: status raw=%q", data)
|
||||
}
|
||||
sawOperate := false
|
||||
for _, pair := range strings.Fields(data) {
|
||||
kv := strings.SplitN(pair, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
@@ -358,6 +375,7 @@ func (c *Client) parse(resp string) {
|
||||
case "state":
|
||||
c.status.State = kv[1]
|
||||
case "operate":
|
||||
sawOperate = true
|
||||
c.status.Operate = kv[1] == "1"
|
||||
case "fanmode":
|
||||
dev := strings.ToUpper(kv[1])
|
||||
@@ -387,6 +405,23 @@ func (c *Client) parse(resp string) {
|
||||
c.status.PeakId, _ = strconv.ParseFloat(kv[1], 64)
|
||||
}
|
||||
}
|
||||
// THE AMP DOES NOT SEND "operate=".
|
||||
//
|
||||
// Operate was therefore never read at all on this link: it stayed at the
|
||||
// zero value until the operator pressed the button, so OpsLog opened
|
||||
// claiming STANDBY on an amplifier that was in line — and the first press
|
||||
// then commanded the state it was already in. Reported from a real PGXL.
|
||||
//
|
||||
// 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 (see
|
||||
// flexAmp): anything but STANDBY/OFF means the amp is IN LINE. IDLE is
|
||||
// operate — in line, not keyed.
|
||||
if !sawOperate && c.status.State != "" {
|
||||
if op, known := operateFromState(c.status.State); known {
|
||||
c.status.Operate = op
|
||||
}
|
||||
}
|
||||
|
||||
c.statusMu.Unlock()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user