diff --git a/docs/API-NAVIGATION-REFERENCE.md b/docs/API-NAVIGATION-REFERENCE.md index 85270e3..c97d220 100644 --- a/docs/API-NAVIGATION-REFERENCE.md +++ b/docs/API-NAVIGATION-REFERENCE.md @@ -143,7 +143,7 @@ Browse stored/local music library. **Example:** ```go -library, err := client.GetStoredMusicLibrary("A81B6A536A98/0") +library, err := client.GetStoredMusicLibrary("AABBCCDDEEFF/0") ``` **Validation:** @@ -526,7 +526,7 @@ Search for stations and content. **Response Body:** ```xml - + Love Story @@ -707,7 +707,7 @@ Navigation and station operations generate WebSocket events: Generated when stations are added/removed that affect presets. ```xml - + @@ -719,7 +719,7 @@ Generated when stations are added/removed that affect presets. Generated when station operations affect current playback. ```xml - + Taylor Swift Radio diff --git a/docs/REQUEST_RECORDING_CONCEPT.md b/docs/REQUEST_RECORDING_CONCEPT.md index 3766bd3..6a5510c 100644 --- a/docs/REQUEST_RECORDING_CONCEPT.md +++ b/docs/REQUEST_RECORDING_CONCEPT.md @@ -15,14 +15,14 @@ The current request recording system has fundamental issues when dealing with re **Local Recording** (complete): ```http -### POST /v1/scmudc/A81B6A536A98 -POST /v1/scmudc/A81B6A536A98 +### POST /v1/scmudc/AABBCCDDEEFF +POST /v1/scmudc/AABBCCDDEEFF Host: events.api.bosecm.com Content-Type: text/json; charset=utf-8 Content-Length: 587 Authorization: Bearer jGwEmFWr... -{"envelope":{"monoTime":234906,"payloadProtocolVersion":"3.1","payloadType":"scmudc","protocolVersion":"1.0","time":"2026-02-25T23:03:14.976349+00:00","uniqueId":"A81B6A536A98"},"payload":{"deviceInfo":{"boseID":"3230304","deviceID":"A81B6A536A98","deviceType":"SoundTouch 10","serialNumber":"I6332527703739342000020","softwareVersion":"27.0.6.46330.5043500 epdbuild.trunk.hepdswbld04.2022-08-04T11:20:29","systemSerialNumber":"069231P63364828AE"},"events":[{"data":{"play-state":"PAUSE_STATE"},"monoTime":234904,"time":"2026-02-25T23:03:14.973466+00:00","type":"play-state-changed"}]}} +{"envelope":{"monoTime":234906,"payloadProtocolVersion":"3.1","payloadType":"scmudc","protocolVersion":"1.0","time":"2026-02-25T23:03:14.976349+00:00","uniqueId":"AABBCCDDEEFF"},"payload":{"deviceInfo":{"boseID":"3230304","deviceID":"AABBCCDDEEFF","deviceType":"SoundTouch 10","serialNumber":"I6332527703739342000020","softwareVersion":"27.0.6.46330.5043500 epdbuild.trunk.hepdswbld04.2022-08-04T11:20:29","systemSerialNumber":"069231P63364828AE"},"events":[{"data":{"play-state":"PAUSE_STATE"},"monoTime":234904,"time":"2026-02-25T23:03:14.973466+00:00","type":"play-state-changed"}]}} {% raw %} > {% @@ -33,8 +33,8 @@ Authorization: Bearer jGwEmFWr... **Mirror Recording** (missing body): ```http -### POST /v1/scmudc/A81B6A536A98 -POST /v1/scmudc/A81B6A536A98 +### POST /v1/scmudc/AABBCCDDEEFF +POST /v1/scmudc/AABBCCDDEEFF Host: events.api.bosecm.com Content-Type: text/json; charset=utf-8 Content-Length: 587 diff --git a/docs/SCMUDC-ENRICHMENT-IMPLEMENTATION.md b/docs/SCMUDC-ENRICHMENT-IMPLEMENTATION.md index 21d7084..07fba48 100644 --- a/docs/SCMUDC-ENRICHMENT-IMPLEMENTATION.md +++ b/docs/SCMUDC-ENRICHMENT-IMPLEMENTATION.md @@ -59,8 +59,8 @@ Based on analysis of recorded data: ### Before (Raw) ```http -### POST /v1/scmudc/A81B6A536A98 -POST /v1/scmudc/A81B6A536A98 +### POST /v1/scmudc/AABBCCDDEEFF +POST /v1/scmudc/AABBCCDDEEFF Host: events.api.bosecm.com ... @@ -69,7 +69,7 @@ Host: events.api.bosecm.com ### After (Enriched) ```http -### POST /v1/scmudc/A81B6A536A98 +### POST /v1/scmudc/AABBCCDDEEFF // Origin: Internal System (device) // Action: play-item // Command: Billie Eilish - bad guy (instrumental version) @@ -87,7 +87,7 @@ Host: events.api.bosecm.com // Billie Eilish - bad guy (instrumental version) // https://i.scdn.co/image/ab67616d0000b273... // -POST /v1/scmudc/A81B6A536A98 +POST /v1/scmudc/AABBCCDDEEFF ... {% raw %} diff --git a/docs/analysis/SETUP-WEBSOCKET-EXPERIMENT.md b/docs/analysis/SETUP-WEBSOCKET-EXPERIMENT.md index 60c4db9..58c2bea 100644 --- a/docs/analysis/SETUP-WEBSOCKET-EXPERIMENT.md +++ b/docs/analysis/SETUP-WEBSOCKET-EXPERIMENT.md @@ -178,7 +178,7 @@ One row per device tested. Once two devices on different firmware confirm the sa - Date: 2026-05-13 - Firmware: 27.0.6.46330.5043500 (build epdbuild.trunk.hepdswbld04.2022-08-04T11:20:29) -- Model: SoundTouch 10 (deviceID A81B6A536A98) +- Model: SoundTouch 10 (deviceID AABBCCDDEEFF) - Bare setMargeAccount accepted: **yes** — pre-/info margeAccountUUID="" → post-/info margeAccountUUID="1111111" - Persistence written: **yes** — device materialized 14-entry Sources.xml on its own - Survives reboot: **yes** — `setup inspect` after `setup reboot` shows margeAccountUUID still 1111111 diff --git a/docs/analysis/SUPPORTED-URLS.md b/docs/analysis/SUPPORTED-URLS.md index 1ee8f08..8e83735 100644 --- a/docs/analysis/SUPPORTED-URLS.md +++ b/docs/analysis/SUPPORTED-URLS.md @@ -6,7 +6,7 @@ This document provides a comprehensive analysis of the `/supportedURLs` endpoint **Test Devices:** - Device 1: `192.0.2.11:8090` (deviceID: `08DF1F0BA325`) -- Device 2: `192.0.2.10:8090` (deviceID: `A81B6A536A98`) +- Device 2: `192.0.2.10:8090` (deviceID: `AABBCCDDEEFF`) **Key Findings:** - Both devices return identical endpoint lists diff --git a/docs/concepts/technical-specification.md b/docs/concepts/technical-specification.md index c3f6f2e..3133c80 100644 --- a/docs/concepts/technical-specification.md +++ b/docs/concepts/technical-specification.md @@ -368,14 +368,14 @@ POST /api/v1/accounts/{account_id}/devices Content-Type: application/json { - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "name": "Living Room Speaker", "registration_type": "fresh" } Response: 201 Created { - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "account_id": "acc_12345", "state": "registering", "created_at": "2024-01-20T10:00:00Z" @@ -388,7 +388,7 @@ GET /api/v1/accounts/{account_id}/devices/{device_id}/state Response: 200 OK { - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "account_id": "acc_12345", "state": "active", "metadata": { @@ -555,7 +555,7 @@ Response: 200 OK ```json { "version": "1.0", - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "account_id": "acc_12345", "state": "active", "created_at": "2024-01-20T10:00:00Z", @@ -585,7 +585,7 @@ Response: 200 OK "type": "SoundTouch 30", "serial_number": "I6332527703739342000020", "firmware_version": "4.8.1.25341.2677643.1597353330", - "mac_address": "A8:1B:6A:53:6A:98", + "mac_address": "AA:BB:CC:DD:EE:FF", "ip_address": "192.168.1.100", "last_seen": "2024-01-20T15:30:00Z", "is_legacy_id": false, @@ -615,7 +615,7 @@ Response: 200 OK ### Event Log Format (events.log) ``` -# SoundTouch Service Event Log - Device A81B6A536A98 +# SoundTouch Service Event Log - Device AABBCCDDEEFF # Format: TIMESTAMP|EVENT_ID|EVENT_TYPE|SOURCE|DATA_JSON # Version: 1.0 @@ -632,8 +632,8 @@ Response: 200 OK # Format: TIMESTAMP|DISPARITY_ID|DEVICE_ID|ACCOUNT_ID|ENDPOINT|TYPE|SEVERITY|DETAILS_JSON # Version: 1.0 -2024-01-20T15:31:15.012Z|disp_12345|A81B6A536A98|acc_12345|/v1/presets|count_mismatch|medium|{"field_path":"preset_count","local_value":5,"upstream_value":4,"description":"Local has one additional preset"} -2024-01-20T15:32:45.678Z|disp_12346|A81B6A536A98|acc_12345|/v1/recents|timestamp_format|low|{"field_path":"recent[0].utc_time","local_value":"2024-01-20T15:30:00Z","upstream_value":"1705761000","description":"Timestamp format difference"} +2024-01-20T15:31:15.012Z|disp_12345|AABBCCDDEEFF|acc_12345|/v1/presets|count_mismatch|medium|{"field_path":"preset_count","local_value":5,"upstream_value":4,"description":"Local has one additional preset"} +2024-01-20T15:32:45.678Z|disp_12346|AABBCCDDEEFF|acc_12345|/v1/recents|timestamp_format|low|{"field_path":"recent[0].utc_time","local_value":"2024-01-20T15:30:00Z","upstream_value":"1705761000","description":"Timestamp format difference"} 2024-01-20T15:35:20.901Z|disp_12347|B92C7B647B09|acc_12345|/v1/account/full|structure_diff|high|{"field_path":"device[1].ip_address","local_value":"present","upstream_value":"missing","description":"IP address field missing in upstream response"} ``` @@ -925,12 +925,12 @@ type ServiceError struct { { "error": { "code": "DEVICE_NOT_FOUND", - "message": "Device with ID 'A81B6A536A98' not found in account 'acc_12345'", + "message": "Device with ID 'AABBCCDDEEFF' not found in account 'acc_12345'", "category": "validation", "timestamp": "2024-01-20T15:30:00Z", "context": { "account_id": "acc_12345", - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "request_id": "req_67890" }, "retryable": false, diff --git a/docs/concepts/upstream-service-simulation.md b/docs/concepts/upstream-service-simulation.md index d4ad458..91e37ec 100644 --- a/docs/concepts/upstream-service-simulation.md +++ b/docs/concepts/upstream-service-simulation.md @@ -111,7 +111,7 @@ data/ ```json { - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "account_id": "account-12345", "state": "active", "created_at": "2024-01-15T10:30:00Z", @@ -137,7 +137,7 @@ data/ "type": "SoundTouch 30", "serial_number": "I6332527703739342000020", "firmware_version": "4.8.1.25341.2677643.1597353330", - "mac_address": "A8:1B:6A:53:6A:98", + "mac_address": "AA:BB:CC:DD:EE:FF", "ip_address": "192.168.1.100", "last_seen": "2024-01-20T16:20:00Z", "is_legacy_id": false @@ -159,7 +159,7 @@ data/ ### Event Log Format ``` -# Device Events Log - A81B6A536A98 +# Device Events Log - AABBCCDDEEFF # Format: TIMESTAMP|EVENT_TYPE|SOURCE|DATA 2024-01-20T16:15:00Z|now_playing|websocket|{"source":"SPOTIFY","track":"Song Name","artist":"Artist Name"} @@ -175,9 +175,9 @@ data/ # Parity Analysis Log # Format: TIMESTAMP|ENDPOINT|DEVICE|ACCOUNT|DISPARITY_TYPE|DETAILS -2024-01-20T16:18:00Z|/v1/account/full|A81B6A536A98|account-12345|content_mismatch|preset_count:local=5,upstream=4 -2024-01-20T16:19:15Z|/v1/presets|A81B6A536A98|account-12345|xml_structure|missing_container_art_in_local -2024-01-20T16:20:30Z|/v1/recents|A81B6A536A98|account-12345|timestamp_format|local=RFC3339,upstream=custom +2024-01-20T16:18:00Z|/v1/account/full|AABBCCDDEEFF|account-12345|content_mismatch|preset_count:local=5,upstream=4 +2024-01-20T16:19:15Z|/v1/presets|AABBCCDDEEFF|account-12345|xml_structure|missing_container_art_in_local +2024-01-20T16:20:30Z|/v1/recents|AABBCCDDEEFF|account-12345|timestamp_format|local=RFC3339,upstream=custom ``` ## Implementation Strategy @@ -268,7 +268,7 @@ POST /api/v1/accounts/{account-id}/devices Content-Type: application/json { - "device_id": "A81B6A536A98", + "device_id": "AABBCCDDEEFF", "name": "Living Room Speaker", "registration_type": "fresh" } diff --git a/docs/device-lifecycle-and-power-on-enhancement.md b/docs/device-lifecycle-and-power-on-enhancement.md index a4cc578..bd463f4 100644 --- a/docs/device-lifecycle-and-power-on-enhancement.md +++ b/docs/device-lifecycle-and-power-on-enhancement.md @@ -169,7 +169,7 @@ The `/power_on` endpoint receives comprehensive device data that could replace m ```xml - + I6332527703739342000020 27.0.6.46330.5043500 epdbuild.trunk.hepdswbld04.2022-08-04T11:20:29 @@ -181,8 +181,8 @@ The `/power_on` endpoint receives comprehensive device data that could replace m Excellent 192.0.2.1 - A81B6A536A98 - A81B6A849D99 + AABBCCDDEEFF + AABBCCDDEE01 192.0.2.10 Wireless diff --git a/docs/device-lifecycle-summary.md b/docs/device-lifecycle-summary.md index 8c5b860..947f6a6 100644 --- a/docs/device-lifecycle-summary.md +++ b/docs/device-lifecycle-summary.md @@ -23,7 +23,7 @@ The `/power_on` endpoint provides rich device data that could eliminate network ### Current /power_on Data ```xml - + I6332527703739342000020 27.0.6.46330.5043500... @@ -35,8 +35,8 @@ The `/power_on` endpoint provides rich device data that could eliminate network Excellent 192.0.2.1 - A81B6A536A98 - A81B6A849D99 + AABBCCDDEEFF + AABBCCDDEE01 192.0.2.10 Wireless diff --git a/docs/guides/MAC-ADDRESS-MAPPING.md b/docs/guides/MAC-ADDRESS-MAPPING.md index d4dbdae..b9fa215 100644 --- a/docs/guides/MAC-ADDRESS-MAPPING.md +++ b/docs/guides/MAC-ADDRESS-MAPPING.md @@ -8,7 +8,7 @@ This guide explains how the SoundTouch service handles device identification thr The SoundTouch service uses two different identifiers for devices: -- **MAC Address** (`A81B6A536A98`) - Used in HTTP API requests and UPnP discovery +- **MAC Address** (`AABBCCDDEEFF`) - Used in HTTP API requests and UPnP discovery - **Serial Number** (`I6332527703739342000020`) - Used for internal file storage The service automatically maps between these identifiers so that API requests using MAC addresses can access files stored using serial numbers. @@ -17,8 +17,8 @@ The service automatically maps between these identifiers so that API requests us ### Request Flow ``` -1. HTTP Request: GET /streaming/account/3230304/device/A81B6A536A98/presets -2. MAC Resolution: A81B6A536A98 → I6332527703739342000020 +1. HTTP Request: GET /streaming/account/3230304/device/AABBCCDDEEFF/presets +2. MAC Resolution: AABBCCDDEEFF → I6332527703739342000020 3. File Access: accounts/3230304/devices/I6332527703739342000020/Presets.xml ``` @@ -26,12 +26,12 @@ The service automatically maps between these identifiers so that API requests us The service extracts MAC addresses from UPnP device descriptions: ```xml - + Sound Machinery SoundTouch 10 - A81B6A536A98 + AABBCCDDEEFF ``` @@ -51,12 +51,12 @@ The service handles all common MAC address formats automatically: | Format | Example | Status | |-------------|---------------------|-------------| -| Standard | `A81B6A536A98` | ✅ Supported | +| Standard | `AABBCCDDEEFF` | ✅ Supported | | Lowercase | `a81b6a536a98` | ✅ Supported | -| With Colons | `A8:1B:6A:53:6A:98` | ✅ Supported | +| With Colons | `AA:BB:CC:DD:EE:FF` | ✅ Supported | | With Dashes | `A8-1B-6A-53-6A-98` | ✅ Supported | | Mixed Case | `a81B6a536A98` | ✅ Supported | -| With Spaces | ` A81B6A536A98 ` | ✅ Supported | +| With Spaces | ` AABBCCDDEEFF ` | ✅ Supported | ## 🔧 **Troubleshooting** @@ -64,9 +64,9 @@ The service handles all common MAC address formats automatically: **Symptoms:** ``` -GET /streaming/account/3230304/device/A81B6A536A98/presets +GET /streaming/account/3230304/device/AABBCCDDEEFF/presets → 500 Internal Server Error -→ Log: "open .../devices/A81B6A536A98/Presets.xml: no such file or directory" +→ Log: "open .../devices/AABBCCDDEEFF/Presets.xml: no such file or directory" ``` **Diagnosis:** @@ -96,7 +96,7 @@ Ensure the MAC address is present: ```xml - A81B6A536A98 + AABBCCDDEEFF 192.0.2.10 @@ -114,7 +114,7 @@ cat > data/accounts/3230304/devices/I6332527703739342000020/DeviceInfo.xml << EO My SoundTouch Device - A81B6A536A98 + AABBCCDDEEFF 192.168.1.100 @@ -126,7 +126,7 @@ EOF **Check UPnP accessibility:** ```bash # Test UPnP endpoint directly -curl http://192.168.1.100:8091/XD/BO5EBO5E-F00D-F00D-FEED-A81B6A536A98.xml +curl http://192.168.1.100:8091/XD/BO5EBO5E-F00D-F00D-FEED-AABBCCDDEEFF.xml # Should return XML with field ``` @@ -144,9 +144,9 @@ This should be handled automatically, but you can verify: **Test different formats:** ```bash # All of these should work the same: -curl http://localhost:8000/streaming/account/3230304/device/A81B6A536A98/presets +curl http://localhost:8000/streaming/account/3230304/device/AABBCCDDEEFF/presets curl http://localhost:8000/streaming/account/3230304/device/a81b6a536a98/presets -curl http://localhost:8000/streaming/account/3230304/device/A8:1B:6A:53:6A:98/presets +curl http://localhost:8000/streaming/account/3230304/device/AA:BB:CC:DD:EE:FF/presets ``` ## 📊 **Monitoring and Diagnostics** @@ -186,8 +186,8 @@ For developers interested in the technical details: // 1. Removing spaces, colons, and dashes // 2. Converting to uppercase // Examples: -// "a8:1b:6a:53:6a:98" → "A81B6A536A98" -// "A8-1B-6A-53-6A-98" → "A81B6A536A98" +// "a8:1b:6a:53:6a:98" → "AABBCCDDEEFF" +// "A8-1B-6A-53-6A-98" → "AABBCCDDEEFF" ``` ### Lookup Process diff --git a/docs/guides/TROUBLESHOOTING.md b/docs/guides/TROUBLESHOOTING.md index bb2b677..dedf6a3 100644 --- a/docs/guides/TROUBLESHOOTING.md +++ b/docs/guides/TROUBLESHOOTING.md @@ -1008,9 +1008,9 @@ Use this checklist to systematically troubleshoot issues: **Symptoms:** ``` -GET /streaming/account/3230304/device/A81B6A536A98/presets +GET /streaming/account/3230304/device/AABBCCDDEEFF/presets → 500 Internal Server Error -→ Log: "open .../devices/A81B6A536A98/Presets.xml: no such file or directory" +→ Log: "open .../devices/AABBCCDDEEFF/Presets.xml: no such file or directory" ``` **Cause:** The service uses MAC addresses in API requests but stores files using device serial numbers. A mapping system resolves MAC addresses to serial numbers automatically. @@ -1026,7 +1026,7 @@ sudo systemctl restart soundtouch-service ```bash # Files should be stored by serial number, not MAC ls data/accounts/3230304/devices/ -# Should show: I6332527703739342000020/ (not A81B6A536A98/) +# Should show: I6332527703739342000020/ (not AABBCCDDEEFF/) ``` 3. **Verify DeviceInfo.xml contains MAC address**: diff --git a/docs/power-on-implementation-guide.md b/docs/power-on-implementation-guide.md index ad016fb..514421e 100644 --- a/docs/power-on-implementation-guide.md +++ b/docs/power-on-implementation-guide.md @@ -504,15 +504,15 @@ func TestHandleMargePowerOnEnhanced(t *testing.T) { }{ { name: "new_device_registration", - requestBody: `...`, + requestBody: `...`, existingDevice: nil, expectedStatus: "ok", expectMigration: false, }, { name: "existing_device_update", - requestBody: `...`, - existingDevice: &models.ServiceDeviceInfo{DeviceID: "A81B6A536A98"}, + requestBody: `...`, + existingDevice: &models.ServiceDeviceInfo{DeviceID: "AABBCCDDEEFF"}, expectedStatus: "ok", expectMigration: true, }, diff --git a/examples/preset-management/README.md b/examples/preset-management/README.md index 4b74fcd..9f25057 100644 --- a/examples/preset-management/README.md +++ b/examples/preset-management/README.md @@ -94,7 +94,7 @@ go run . 192.168.1.100 💾 Storing test preset 4 to trigger event... ⏳ Waiting 3 seconds for WebSocket event... 📡 Preset Update Event Received! - Device: A81B6A536A98 + Device: AABBCCDDEEFF Presets count: 4 - Preset 1: Morning Jazz (SPOTIFY) - Preset 2: K-LOVE Radio (TUNEIN)