Files
Bose-SoundTouch/pkg/models/volume.go
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

103 lines
2.1 KiB
Go

package models
import (
"encoding/xml"
"fmt"
)
// Volume represents the response from GET /volume endpoint
type Volume struct {
XMLName xml.Name `xml:"volume"`
DeviceID string `xml:"deviceID,attr"`
TargetVolume int `xml:"targetvolume"`
ActualVolume int `xml:"actualvolume"`
MuteEnabled bool `xml:"muteenabled"`
}
// VolumeRequest represents the request for POST /volume endpoint
type VolumeRequest struct {
XMLName xml.Name `xml:"volume"`
Value int `xml:",chardata"`
}
// NewVolumeRequest creates a new volume set request
func NewVolumeRequest(volume int) *VolumeRequest {
return &VolumeRequest{
Value: volume,
}
}
// GetLevel returns the current actual volume level
func (v *Volume) GetLevel() int {
return v.ActualVolume
}
// GetTargetLevel returns the target volume level
func (v *Volume) GetTargetLevel() int {
return v.TargetVolume
}
// IsMuted returns whether the device is muted
func (v *Volume) IsMuted() bool {
return v.MuteEnabled
}
// IsVolumeSync returns true if target and actual volumes match
func (v *Volume) IsVolumeSync() bool {
return v.TargetVolume == v.ActualVolume
}
// GetVolumeString returns a formatted string representation
func (v *Volume) GetVolumeString() string {
if v.IsMuted() {
return "Muted"
}
return fmt.Sprintf("%d", v.ActualVolume)
}
// ValidateVolumeLevel checks if a volume level is valid (0-100)
func ValidateVolumeLevel(level int) bool {
return level >= 0 && level <= 100
}
// ClampVolumeLevel ensures a volume level is within valid range
func ClampVolumeLevel(level int) int {
if level < 0 {
return 0
}
if level > 100 {
return 100
}
return level
}
// Volume level constants
const (
VolumeMin = 0
VolumeMax = 100
VolumeMute = 0
VolumeQuiet = 10
VolumeLow = 25
VolumeMedium = 50
VolumeHigh = 75
VolumeLoud = 100
)
// GetVolumeLevelName returns a descriptive name for volume levels
func GetVolumeLevelName(level int) string {
switch {
case level == 0:
return "Mute"
case level <= 10:
return "Very Quiet"
case level <= 25:
return "Quiet"
case level <= 50:
return "Medium"
case level <= 75:
return "High"
default:
return "Loud"
}
}