feat: SPE amp ON/OFF buttons and Low/Mid/High power-level control (keystroke codes best-guess from APG, pending hw verification)
This commit is contained in:
+37
-1
@@ -30,9 +30,17 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
cmdOperate byte = 0x0D // toggles STANDBY ↔ OPERATE
|
||||
cmdOperate byte = 0x0D // toggles STANDBY ↔ OPERATE (confirmed on hw)
|
||||
cmdStatus byte = 0x90 // request the status string
|
||||
|
||||
// Best-guess keystroke codes reconstructed from the APG command table after
|
||||
// correcting the PDF's note-wrap misalignment (anchored to the confirmed
|
||||
// OPERATE=0x0D): OFF=0x0A, POWER=0x0B. The POWER key doubles as power-on (when
|
||||
// the amp is off) and the output-level cycle L→M→H (when it's on) — same as the
|
||||
// single physical POWER button. To be verified on hardware.
|
||||
cmdOff byte = 0x0A // OFF key — switch the amplifier off
|
||||
cmdPower byte = 0x0B // POWER key — turn on / cycle output power level
|
||||
|
||||
syncHost = 0x55
|
||||
syncAmp = 0xAA
|
||||
|
||||
@@ -138,6 +146,34 @@ func (c *Client) Operate(on bool) error {
|
||||
// ToggleOperate flips STANDBY/OPERATE unconditionally.
|
||||
func (c *Client) ToggleOperate() error { return c.sendCmd(cmdOperate) }
|
||||
|
||||
// PowerOn presses the POWER key (turns the amp on when it's off).
|
||||
func (c *Client) PowerOn() error { return c.sendCmd(cmdPower) }
|
||||
|
||||
// PowerOff presses the OFF key (switches the amp off).
|
||||
func (c *Client) PowerOff() error { return c.sendCmd(cmdOff) }
|
||||
|
||||
// SetPowerLevel cycles the output power level (L/M/H) to the requested one by
|
||||
// tapping the POWER key until the reported level matches, giving the amp time to
|
||||
// report each change. `level` is "L", "M" or "H" (case-insensitive).
|
||||
func (c *Client) SetPowerLevel(level string) error {
|
||||
want := strings.ToUpper(strings.TrimSpace(level))
|
||||
if want == "" {
|
||||
return nil
|
||||
}
|
||||
// At most 3 taps to walk the 3-way cycle back around to the target.
|
||||
for i := 0; i < 3; i++ {
|
||||
cur := strings.ToUpper(strings.TrimSpace(c.GetStatus().PowerLevel))
|
||||
if cur == want {
|
||||
return nil
|
||||
}
|
||||
if err := c.sendCmd(cmdPower); err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(1 * time.Second) // let the amp apply it and the poll refresh status
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) pollLoop() {
|
||||
t := time.NewTicker(pollEvery)
|
||||
defer t.Stop()
|
||||
|
||||
Reference in New Issue
Block a user