Complete preset management implementation

- Add comprehensive preset reading functionality with helper methods
- Implement GetNextAvailablePresetSlot() and IsCurrentContentPresetable()
- Add CLI support for viewing presets with -presets flag
- Fix Preset XML tag to use lowercase 'preset' for API compliance
- Update documentation to reflect official API design:
  * GET /presets: fully implemented with rich analysis
  * POST /presets: officially 'N/A' per Bose documentation (not supported by design)
- Add detailed PRESET-MANAGEMENT.md documentation
- Update API endpoints overview and project status
- All tests passing with real device validation

Preset management is now 100% complete according to official API specification.
Read operations provide comprehensive preset analysis, while creation
is intentionally handled by official app/hardware controls per API design.
This commit is contained in:
Tobias Gesellchen
2026-01-09 11:11:10 +01:00
parent 46b7f3c6e7
commit 609cc04c16
6 changed files with 404 additions and 20 deletions
+30
View File
@@ -126,6 +126,36 @@ func (c *Client) GetPresets() (*models.Presets, error) {
return &presets, nil
}
// GetNextAvailablePresetSlot returns the next available preset slot (1-6), or error if all are used
func (c *Client) GetNextAvailablePresetSlot() (int, error) {
presets, err := c.GetPresets()
if err != nil {
return 0, fmt.Errorf("failed to get presets: %w", err)
}
emptySlots := presets.GetEmptyPresetSlots()
if len(emptySlots) == 0 {
return 0, fmt.Errorf("all preset slots are occupied")
}
// Return the first available slot
return emptySlots[0], nil
}
// IsCurrentContentPresetable checks if the currently playing content can be saved as a preset
func (c *Client) IsCurrentContentPresetable() (bool, error) {
nowPlaying, err := c.GetNowPlaying()
if err != nil {
return false, fmt.Errorf("failed to get now playing: %w", err)
}
if nowPlaying.IsEmpty() || nowPlaying.ContentItem == nil {
return false, nil
}
return nowPlaying.ContentItem.IsPresetable, nil
}
// SendKey sends a key press command to the device (press followed by release)
func (c *Client) SendKey(keyValue string) error {
if !models.IsValidKey(keyValue) {
+1
View File
@@ -14,6 +14,7 @@ type Presets struct {
// Preset represents an individual preset
type Preset struct {
XMLName xml.Name `xml:"preset"`
ID int `xml:"id,attr"`
CreatedOn *int64 `xml:"createdOn,attr,omitempty"`
UpdatedOn *int64 `xml:"updatedOn,attr,omitempty"`