Files
Bose-SoundTouch/docs/KEY-CONTROLS.md
T
Tobias Gesellchen b4e6ce7042 feat: implement GET/POST /volume endpoints with press+release key pattern
Volume Control Implementation:
• Complete GET/POST /volume endpoint implementation with XML models
• Volume model with validation, clamping, and safety features
• Client methods: GetVolume(), SetVolume(), IncreaseVolume(), DecreaseVolume()
• CLI commands: -volume, -set-volume, -inc-volume, -dec-volume with safety limits
• Comprehensive volume level categorization and helper methods

Key Controls Enhancement:
• Fix press+release pattern: SendKey() now sends both press and release states
• Follows API documentation requirement for proper key simulation
• Add SendKeyPressOnly() and SendKeyReleaseOnly() for advanced usage
• Update documentation to reflect press+release behavior
• Add test for press+release pattern validation

Safety Features:
• Volume warnings for levels >30 with 2-second delay
• Increment/decrement limits (10 up, 20 down per command)
• Automatic volume clamping to 0-100 range
• Clear volume level descriptions (Mute, Quiet, Medium, High, Loud)

Testing & Documentation:
• Comprehensive volume control tests (30+ test cases)
• Complete documentation in docs/VOLUME-CONTROLS.md
• Updated key controls documentation for press+release pattern
• Real device testing with both SoundTouch 10 and 20
• All tests pass, no diagnostics errors

Real Device Integration:
• Fixed volume key press issues through proper press+release cycle
• Tested volume API endpoints with actual devices
• Safe volume levels maintained during testing

Breaking Changes: None
Backward Compatibility: Fully maintained

Production Ready:
 Volume control endpoints (GET/POST /volume)
 Enhanced key controls with proper press+release pattern
 Comprehensive safety features for volume management
 Real device validation and testing
2026-01-08 23:56:17 +01:00

7.2 KiB

Key Control Implementation

This document describes the implementation of the POST /key endpoint for media control commands in the Bose SoundTouch API client.

Overview

The key control functionality allows sending media control commands to SoundTouch devices, including play/pause, volume adjustment, track navigation, and preset selection.

Implementation Files

  • pkg/models/key.go - XML model and constants for key commands
  • pkg/models/key_test.go - Comprehensive tests for key functionality
  • pkg/client/client.go - Client methods for sending key commands
  • cmd/soundtouch-cli/main.go - CLI commands for key controls

API Specification

POST /key

Sends a key command to the SoundTouch device.

Request Format: According to the API documentation, proper key simulation requires sending both press and release states:

<key state="press" sender="Gabbo">KEY_NAME</key>
<key state="release" sender="Gabbo">KEY_NAME</key>

Response Format:

<?xml version="1.0" encoding="UTF-8" ?>
<status>/key</status>

Important Discovery: Sender Field

During implementation, we discovered that the sender attribute is critical for successful key commands. Only specific sender values are accepted:

  • "Gabbo" - Works (canonical example from official documentation)
  • "GoClient" - Rejected with CLIENT_XML_ERROR (1019)
  • "SoundTouch app" - Rejected with CLIENT_XML_ERROR (1019)
  • "" (empty) - Rejected with CLIENT_XML_ERROR (1019)

Our implementation uses "Gabbo" as the default sender, which is the standard value used in official SoundTouch examples.

Available Key Commands

Media Controls

  • PLAY - Start playback
  • PAUSE - Pause playback
  • STOP - Stop playback
  • PREV_TRACK - Previous track
  • NEXT_TRACK - Next track

Volume Controls

  • VOLUME_UP - Increase volume
  • VOLUME_DOWN - Decrease volume

Presets

  • PRESET_1 through PRESET_6 - Select preset 1-6

Client API

Basic Methods

// Send complete key command (press + release - recommended)
err := client.SendKey(models.KeyPlay)

// Send key press and release (alias for SendKey)
err := client.SendKeyPress(models.KeyPlay)

// Send only key press state (advanced usage)
err := client.SendKeyPressOnly(models.KeyPlay)

// Send only key release state (advanced usage)
err := client.SendKeyReleaseOnly(models.KeyPlay)

Convenience Methods

// Media controls
err := client.Play()
err := client.Pause()
err := client.Stop()
err := client.NextTrack()
err := client.PrevTrack()

// Volume controls
err := client.VolumeUp()
err := client.VolumeDown()

// Preset selection (1-6)
err := client.SelectPreset(1)

Key Validation

// Check if a key value is valid
isValid := models.IsValidKey("PLAY") // true
isValid := models.IsValidKey("INVALID") // false

// Get all valid key values
allKeys := models.GetAllValidKeys()

CLI Usage

Individual Key Commands

# Media controls
soundtouch-cli -host 192.168.1.100 -play
soundtouch-cli -host 192.168.1.100 -pause
soundtouch-cli -host 192.168.1.100 -stop
soundtouch-cli -host 192.168.1.100 -next
soundtouch-cli -host 192.168.1.100 -prev

# Volume controls
soundtouch-cli -host 192.168.1.100 -volume-up
soundtouch-cli -host 192.168.1.100 -volume-down

# Preset selection
soundtouch-cli -host 192.168.1.100 -preset 1
soundtouch-cli -host 192.168.1.100 -preset 6

Generic Key Command

# Send any valid key using the -key flag
soundtouch-cli -host 192.168.1.100 -key PLAY
soundtouch-cli -host 192.168.1.100 -key STOP
soundtouch-cli -host 192.168.1.100 -key PRESET_3

Error Handling

# Invalid key validation
$ soundtouch-cli -host 192.168.1.100 -key INVALID
Failed to send key command: invalid key value: INVALID

# Multiple commands rejected
$ soundtouch-cli -host 192.168.1.100 -play -pause
Failed to send key command: only one key command can be sent at a time

# Missing host
$ soundtouch-cli -play
Host is required for key commands. Use -host flag or -discover to find devices.

Testing

Unit Tests

The implementation includes comprehensive unit tests in pkg/models/key_test.go:

  • XML marshaling/unmarshaling
  • Key validation
  • Constructor functions
  • Constants validation
  • Benchmark tests

Run tests:

go test ./pkg/models/...

Integration Testing

Tested with real SoundTouch devices:

  • SoundTouch 10 (192.168.1.100:8090)
  • SoundTouch 20 (192.168.1.35:8090)

All key commands successfully sent and executed on both devices.

Code Examples

Basic Usage

package main

import (
    "log"
    "github.com/user_account/bose-soundtouch/pkg/client"
    "github.com/user_account/bose-soundtouch/pkg/models"
)

func main() {
    // Create client
    soundtouchClient := client.NewClientFromHost("192.168.1.100")
    
    // Play music
    if err := soundtouchClient.Play(); err != nil {
        log.Fatalf("Failed to play: %v", err)
    }
    
    // Adjust volume
    if err := soundtouchClient.VolumeUp(); err != nil {
        log.Fatalf("Failed to increase volume: %v", err)
    }
    
    // Select preset
    if err := soundtouchClient.SelectPreset(1); err != nil {
        log.Fatalf("Failed to select preset: %v", err)
    }
}

Advanced Usage with Validation

func sendKeyCommand(client *client.Client, keyValue string) error {
    // Validate before sending
    if !models.IsValidKey(keyValue) {
        return fmt.Errorf("invalid key: %s", keyValue)
    }
    
    // SendKey automatically sends both press and release states
    return client.SendKey(keyValue)
}

func sendAllValidKeys(client *client.Client) {
    for _, key := range models.GetAllValidKeys() {
        fmt.Printf("Sending key: %s (press+release)\n", key)
        if err := client.SendKey(key); err != nil {
            log.Printf("Failed to send %s: %v", key, err)
        }
        time.Sleep(1 * time.Second) // Avoid overwhelming the device
    }
}

Implementation Notes

  1. Press + Release Pattern: Following API documentation, SendKey() sends both press and release states for proper key simulation
  2. Sender Field Critical: The sender attribute must be "Gabbo" for commands to be accepted
  3. XML Format: Simple XML structure without namespaces or headers
  4. State Handling: Both "press" and "release" states are supported, with complete press+release cycle as default
  5. Input Validation: All key values are validated before sending to the device
  6. Error Handling: Comprehensive error handling for invalid keys and API errors
  7. CLI Safety: Only one key command allowed per CLI invocation to prevent conflicts

Future Enhancements

Potential areas for future development:

  1. Key Sequences: Support for sending multiple key commands in sequence
  2. Macros: Predefined key command sequences (e.g., "power on and play preset 1")
  3. Key Hold: Support for key hold duration for volume changes
  4. Device State: Check device state before sending commands
  5. Async Commands: Non-blocking key command execution
  6. Key Mapping: Custom key mappings for different device types

Reference

  • Official API: Based on Bose SoundTouch Web API documentation
  • Test Devices: Validated with SoundTouch 10 and SoundTouch 20
  • Standards: Follows existing project patterns and conventions