mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
Add PlayNotification support for device-local PCM files and expose it via CLI
This commit is contained in:
+23
-2
@@ -1801,8 +1801,29 @@ func (c *Client) PlayCustom(playInfo *models.PlayInfo) error {
|
||||
|
||||
// PlayNotificationBeep plays a notification beep on the device
|
||||
func (c *Client) PlayNotificationBeep() error {
|
||||
var status models.StationResponse
|
||||
return c.get("/playNotification", &status)
|
||||
return c.PlayNotification("")
|
||||
}
|
||||
|
||||
// PlayNotification plays a notification. If a non-empty local path is provided,
|
||||
// it will be sent as XML body to play that specific device-local PCM file.
|
||||
// When path is empty, the device's default beep is triggered.
|
||||
func (c *Client) PlayNotification(path string) error {
|
||||
// Empty path -> trigger default beep via GET
|
||||
if strings.TrimSpace(path) == "" {
|
||||
var status models.StationResponse
|
||||
return c.get("/playNotification", &status)
|
||||
}
|
||||
|
||||
// Non-empty path -> POST minimal XML payload as required by the device
|
||||
payload := struct {
|
||||
XMLName xml.Name `xml:"audioSource"`
|
||||
PathToFile string `xml:"pathToFile,attr"`
|
||||
}{
|
||||
XMLName: xml.Name{Local: "audioSource"},
|
||||
PathToFile: path,
|
||||
}
|
||||
|
||||
return c.post("/playNotification", payload)
|
||||
}
|
||||
|
||||
// Introspect retrieves introspect data for a specified music service
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
@@ -1160,3 +1161,71 @@ func TestClient_RequestToken_Error(t *testing.T) {
|
||||
t.Errorf("Error should mention 'failed to request token', got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_PlayNotificationBeep(t *testing.T) {
|
||||
// Create mock server
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/playNotification" {
|
||||
t.Errorf("Expected path '/playNotification', got '%s'", r.URL.Path)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method != http.MethodGet {
|
||||
t.Errorf("Expected GET method, got %s", r.Method)
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/xml")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="UTF-8" ?><status>success</status>`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
// Create test client
|
||||
client := createTestClient(server.URL)
|
||||
|
||||
// Test PlayNotificationBeep
|
||||
err := client.PlayNotificationBeep()
|
||||
if err != nil {
|
||||
t.Fatalf("PlayNotificationBeep() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClient_PlayNotification_Path(t *testing.T) {
|
||||
testPath := "/opt/Bose/chimes/grouped.pcm"
|
||||
|
||||
// Create mock server
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/playNotification" {
|
||||
t.Errorf("Expected path '/playNotification', got '%s'", r.URL.Path)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method != http.MethodPost {
|
||||
t.Errorf("Expected POST method, got %s", r.Method)
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
expectedXML := `<audioSource pathToFile="` + testPath + `"></audioSource>`
|
||||
if string(body) != expectedXML {
|
||||
t.Errorf("Expected body '%s', got '%s'", expectedXML, string(body))
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
// Create test client
|
||||
client := createTestClient(server.URL)
|
||||
|
||||
// Test PlayNotification with path
|
||||
err := client.PlayNotification(testPath)
|
||||
if err != nil {
|
||||
t.Fatalf("PlayNotification() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user