Documentation for controlling and preserving Bose SoundTouch devices
This document describes the various methods available for discovering Bose SoundTouch devices on your network.
The SoundTouch library supports multiple discovery methods to find devices on your network:
.env fileYou can manually configure known devices in your .env file:
PREFERRED_DEVICES=Living Room:192.168.1.100:8090,Kitchen:192.168.1.101:8090
This method is:
Uses the Universal Plug and Play protocol to discover devices automatically. This is enabled by default.
Configuration:
UPNP_ENABLED=true # Default: true
This method is:
Uses multicast DNS to discover devices advertising the _soundtouch._tcp service.
Configuration:
MDNS_ENABLED=true # Default: true
This method is:
# Discovery timeouts
DISCOVERY_TIMEOUT=5s # How long to wait for discovery
# Protocol enablement
UPNP_ENABLED=true # Enable UPnP/SSDP discovery
MDNS_ENABLED=true # Enable mDNS/Bonjour discovery
# Caching
CACHE_ENABLED=true # Enable discovery result caching
CACHE_TTL=30s # How long to cache results
# Manual device configuration
PREFERRED_DEVICES=Name:IP:Port,Name2:IP2:Port2
# Discovery settings
DISCOVERY_TIMEOUT=10s
UPNP_ENABLED=true
MDNS_ENABLED=true
# Cache settings
CACHE_ENABLED=true
CACHE_TTL=60s
# Known devices (fastest method)
PREFERRED_DEVICES=Living Room:192.168.1.100:8090,Kitchen:192.168.1.101:8090,Bedroom:192.168.1.102
# Discover all devices using all methods
./soundtouch-cli -discover
# Discover with custom timeout
./soundtouch-cli -discover -timeout 10s
# Show detailed device information
./soundtouch-cli -discover-all
package main
import (
"context"
"fmt"
"time"
"github.com/gesellix/bose-soundtouch/pkg/config"
"github.com/gesellix/bose-soundtouch/pkg/discovery"
)
func main() {
// Load configuration
cfg, err := config.LoadFromEnv()
if err != nil {
cfg = config.DefaultConfig()
}
// Create unified discovery service
discoveryService := discovery.NewUnifiedDiscoveryService(cfg)
// Discover devices
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
devices, err := discoveryService.DiscoverDevices(ctx)
if err != nil {
fmt.Printf("Discovery failed: %v\n", err)
return
}
// Print results
for _, device := range devices {
fmt.Printf("Found: %s at %s:%d\n", device.Name, device.Host, device.Port)
}
}
package main
import (
"context"
"time"
"github.com/gesellix/bose-soundtouch/pkg/discovery"
)
func main() {
// Create mDNS-only discovery service
mdnsService := discovery.NewMDNSDiscoveryService(5 * time.Second)
ctx := context.Background()
devices, err := mdnsService.DiscoverDevices(ctx)
// Handle results...
}
.env fileCACHE_ENABLED=truemDNS discovery may fail if:
_soundtouch._tcp serviceUPnP discovery may fail if:
The unified discovery service uses this flow:
Each discovered device includes:
Name: Device name (from config or auto-detected)Host: IP addressPort: Port number (usually 8090)Location: Full device URLLastSeen: When the device was discoveredtype DiscoveredDevice struct {
Name string
Host string
Port int
Location string
LastSeen time.Time
}
UnifiedDiscoveryService: Uses all available discovery methodsDiscoveryService: UPnP/SSDP only (legacy)MDNSDiscoveryService: mDNS/Bonjour onlyDiscoverDevices(ctx): Discover all devicesDiscoverDevice(ctx, host): Find specific deviceGetCachedDevices(): Get cached resultsClearCache(): Clear discovery cache