[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
0

Configure Feed

Select the types of activity you want to include in your feed.

feat(sonos): Fix first media seen logging and add debug guidance to docs

add env gate to sonos test playground

FoxxMD (Jan 22, 2026, 1:48 PM UTC) 54eabf49 16ad50ca

+75 -9
+53 -1
docsite/docs/configuration/sources/sonos.mdx
··· 25 25 26 26 If you have other Sources configured for Multi-Scrobbler that you may play *through Sonos* you should try to add Sonos to the "deny" list for that Source so that it does not try to monitor Sonos activity. Check the documentation for each individual Source to see how to configure this exclusion. 27 27 28 - An example of this for [Plex](/configuration/sources/plex) would be to add Sonos to the "block" list ENV EX: `PLEX_DEVICES_BLOCK=sonos` 28 + For example, to prevent the [Plex](/configuration/sources/plex) Source from monitoring audio played through Sonos, add Sonos to the "block" list ENV EX: `PLEX_DEVICES_BLOCK=sonos` 29 29 30 30 ::: 31 + 32 + <details> 33 + 34 + <summary>How to report issues</summary> 35 + 36 + If your Sonos Source is logging errors or the scrobble data is not as expected please [create a bug report](https://github.com/FoxxMD/multi-scrobbler/issues/new?template=01-bug-report.yml) **after** enabling the following debug logging options based on the config type you have: 37 + 38 + <Tabs groupdId="sonosBugConfig"> 39 + <TabItem value="env" label="ENV"> 40 + 41 + Enable [Debug Mode](/configuration#debug-mode) using `DEBUG_MODE=true` 42 + 43 + </TabItem> 44 + <TabItem value="file" label="File"> 45 + 46 + Enable `logPayload` and `logFitlerFailure` in your `sonos.json`, or AIO file, config: 47 + 48 + ```json 49 + [ 50 + { 51 + "enable": true, 52 + "name": "MySonos", 53 + "data": { 54 + "host": "192.168.0.150" 55 + }, 56 + "options": { 57 + "logFilterFailure": "warn", 58 + "logPayload": true 59 + } 60 + } 61 + ] 62 + ``` 63 + 64 + </TabItem> 65 + 66 + </Tabs> 67 + 68 + Additional logging for the Sonos library may be enabled by including this environmental variable (regardless of config type): 69 + 70 + ``` 71 + DEBUG=sonos:* 72 + ``` 73 + 74 + The above changes: 75 + 76 + * Triggers multi-scrobbler to log the raw data recieved from Sonos when a new track/device/service is seen for the first time 77 + * Trigger multi-scrobbler to log the reason it considers a play from Sonos as invalid (and will not monitor it) 78 + * Logs low-level activity from the Sonos library 79 + 80 + Please include these additional logs when creating a bug report. They are essential to troubleshooting your issue. 81 + 82 + </details> 31 83 32 84 ## Configuration 33 85
+6 -2
src/backend/sources/SonosSource.ts
··· 129 129 let status = CLIENT_PLAYER_STATE[x.state.transportState]; 130 130 131 131 let seen = true; 132 - if (!this.mediaIdsSeen.data.includes(x.state.positionInfo.TrackURI)) { 132 + 133 + // TrackURI seems to correspond to 1) the device/group playing and 2) the service/source playing 134 + // but NOT the content actually playing -- 2) does not update when content playing changes on the same service 135 + const mediaId = `${x.state.positionInfo.TrackURI}--${typeof x.state.positionInfo.TrackMetaData !== 'string' ? x.state.positionInfo.TrackMetaData.TrackUri : x.state.positionInfo.TrackMetaData}`; 136 + if (!this.mediaIdsSeen.data.includes(mediaId)) { 133 137 seen = false; 134 - this.mediaIdsSeen.add(x.state.positionInfo.TrackURI); 138 + this.mediaIdsSeen.add(mediaId); 135 139 if (this.config.options?.logPayload || isDebugMode()) { 136 140 this.logger.debug({ device: { Name, GroupName, Uuid }, state: x.state }, 'Sonos Data'); 137 141 }
+16 -6
src/backend/tests/sonos/sonos.test.ts
··· 20 20 return source; 21 21 } 22 22 23 - // it('does stuff', async function() { 23 + describe('#Sonos', function() { 24 24 25 - // const s = await createSource({host: process.env.SONOS_HOST}); 26 - // await s.checkConnection(); 27 - // await s.getRecentlyPlayed(); 28 - // const f = 1; 29 - // }); 25 + before(function () { 26 + if (process.env.SONOS_TEST !== 'true') { 27 + this.skip(); 28 + } 29 + }); 30 + 31 + it('does stuff', async function() { 32 + 33 + const s = await createSource({host: process.env.SONOS_HOST_TEST}); 34 + await s.checkConnection(); 35 + await s.getRecentlyPlayed(); 36 + const f = 1; 37 + }); 38 + 39 + });