Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔇Added device filtering (actually added heh) #41

Merged
merged 3 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions MMM-OnSpotify.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ Module.register("MMM-OnSpotify", {
// state, as user data does not change that much, this prevents unnecessary api calls.
userDataMaxAge: 14400,
userAffinityMaxAge: 36000,
// Filter which devices show up in the module
deviceFilter: [],
deviceFilterExclude: false,
filterNoticeSubtitle: true,

updateInterval: {
isPlaying: 1,
Expand Down Expand Up @@ -137,7 +141,7 @@ Module.register("MMM-OnSpotify", {
typeof this.config.theming.experimentalCSSOverridesForMM2 === "object";

////////////////////////////////////////////////////////////////////////////////////////////
this.version = "3.1.0";
this.version = "3.2.0";
////////////////////////////////////////////////////////////////////////////////////////////

this.displayUser =
Expand Down Expand Up @@ -190,6 +194,8 @@ Module.register("MMM-OnSpotify", {
this.sendSocketNotification("SET_CREDENTIALS_REFRESH", {
preferences: {
userAffinityUseTracks: this.config.userAffinityUseTracks,
deviceFilter: this.config.deviceFilter,
deviceFilterExclude: this.config.deviceFilterExclude,
},
credentials: {
clientId: this.config.clientID,
Expand Down Expand Up @@ -352,7 +358,12 @@ Module.register("MMM-OnSpotify", {
});
break;
case "USER_DATA":
this.userData = payload;
this.userData = {
...payload,
subtitleOverride:
this.playerData && this.config.filteredDeviceNotice ?
this.playerData.notAllowedDevice : false,
};
this.userData.age = Date.now();
this.requestUserData = false;
this.smartUpdate("USER_DATA");
Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,12 @@ Once you finish, you are all set with the basic configuration. Scroll down to se
userAffinityUseTracks: false,
prefersLargeImageSize: false,
hideTrackLenghtAndAnimateProgress: false,
showDebugPalette: true,
showDebugPalette: false,
userDataMaxAge: 14400,
userAffinityMaxAge: 36000,
deviceFilter: [],
deviceFilterExclude: false,
filterNoticeSubtitle: true,
// Update intervals [SEE BELOW]
isPlaying: 1,
isEmpty: 2,
Expand All @@ -87,9 +90,9 @@ Once you finish, you are all set with the basic configuration. Scroll down to se
useColorInTitle: true,
useColorInUserData: true,
showBlurBackground: true,
blurCorrectionInFrameSide: true,
blurCorrectionInAllSides: true,
alwaysUseDefaultDeviceIcon: true,
blurCorrectionInFrameSide: false,
blurCorrectionInAllSides: false,
alwaysUseDefaultDeviceIcon: false,
experimentalCSSOverridesForMM2: false, // [SEE BELOW]
},
},
Expand Down Expand Up @@ -123,6 +126,9 @@ experimentalCSSOverridesForMM2: [
| showDebugPalette <br> `false` | Shows the Vibrant output as a palette in the web console. <br /><br /> <img alt="Debug palette" src=".github/content/readme/image-debugpalette.png" width="80%"> |
| userDataMaxAge <br> `14400` | (Seconds) The time in seconds of user data TTL. If set to 0, its updated everytime that the player goes to idle, as user data rarely changes, this allows a middle ground between updating always and only on boot |
| userAffinityMaxAge <br> `36000` | (Seconds) The time in seconds of affinity data TTL. If set to 0, its updated everytime that the player goes to idle, as user data rarely changes, this allows a middle ground between updating always and only on boot |
| deviceFilter <br> `list[]` | List of device names to filter from the module, by default, its an inclusion list, you can change this using `deviceFilterExclude` (making it an exclusion list). When a filtered device plays `displayWhenEmpty` shows. Example: `["Sonos Bedroom", "DESKTOP-ABCD123"]` |
| deviceFilterExclude <br> `false` | Inverts the `deviceFilter` list, making it exclude devices |
| filterNoticeSubtitle <br> `true`| Changes the subtitle of `displayWhenEmpty`, to not show a false status if the `deviceFilter` is set |

### Polling Intervals:
| Key | Description |
Expand Down
33 changes: 33 additions & 0 deletions node_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ module.exports = NodeHelper.create({
this.lastDeviceName = null;
// The times that an available (but empty) player has been returned by the api
this.isPlayerInTransit = 0;
// Configuration sent to the helper
this.preferences = null;
},

socketNotificationReceived: function (notification, payload) {
switch (notification) {
case "SET_CREDENTIALS_REFRESH":
this.fetcher = new SpotifyFetcher(payload);
this.fetchSpotifyData("PLAYER");
this.preferences = payload.preferences
break;
case "REFRESH_PLAYER":
this.fetchSpotifyData("PLAYER");
Expand Down Expand Up @@ -57,6 +60,24 @@ module.exports = NodeHelper.create({
);
switch (type) {
case "PLAYER":
// CASE S1 The data is OK and the target is a filtered device
if (data && data.device && data.device.name && !this.isAllowedDevice(data.device.name)) {
this.sendSocketNotification("PLAYER_DATA", {
statusIsPlayerEmpty: true,
statusIsNewSong: false,
statusIsChangeToEmptyPlayer: this.lastPlayerStatus,
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: false,
statusIsDeviceChange: false,
notAllowedDevice: data.device.name
});
this.lastMediaUri = "empty";
this.lastPlayerStatus = false;
this.lastPlayerStatusCount = 0;
this.lastDeviceName = "unknown";
break
}
// CASE S2 The data is OK and the target is in a private session
if (data && data.device && data.device.is_private_session) {
let payload = {
/* Player data */
Expand All @@ -76,6 +97,7 @@ module.exports = NodeHelper.create({
statusPlayerUpdating: false,
statusIsDeviceChange:
this.lastDeviceName !== data.device.name ? true : false,
notAllowedDevice: false
};
this.sendSocketNotification("PLAYER_DATA", payload);
this.lastMediaUri = "privatesession";
Expand All @@ -84,6 +106,7 @@ module.exports = NodeHelper.create({
this.lastPlayerStatusCount = 0;
break;
}

if (data && data.item) {
// CASE 1 The data is OK and there is an ITEM in the player
let isTrack =
Expand Down Expand Up @@ -127,6 +150,7 @@ module.exports = NodeHelper.create({
statusPlayerUpdating: false,
statusIsDeviceChange:
this.lastDeviceName !== data.device.name ? true : false,
notAllowedDevice: false
};
this.sendSocketNotification("PLAYER_DATA", payload);
this.lastMediaUri = data.item.uri;
Expand All @@ -145,6 +169,7 @@ module.exports = NodeHelper.create({
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: true,
statusIsDeviceChange: false,
notAllowedDevice: false
});
this.lastPlayerStatusCount = this.lastPlayerStatusCount + 1;
this.lastPlayerStatus = true;
Expand All @@ -157,6 +182,7 @@ module.exports = NodeHelper.create({
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: false,
statusIsDeviceChange: false,
notAllowedDevice: false
});
this.lastMediaUri = "empty";
this.lastPlayerStatus = false;
Expand All @@ -171,6 +197,7 @@ module.exports = NodeHelper.create({
statusIsChangeToMediaPlayer: false,
statusPlayerUpdating: false,
statusIsDeviceChange: false,
notAllowedDevice: false
});
this.lastMediaUri = "empty";
this.lastPlayerStatus = false;
Expand Down Expand Up @@ -226,6 +253,12 @@ module.exports = NodeHelper.create({
}
},

isAllowedDevice: function (currentDevice) {
if (!this.preferences.deviceFilter || this.preferences.deviceFilter.length < 1) return true
return this.preferences.deviceFilterExclude ?
!this.preferences.deviceFilter.includes(currentDevice) :
this.preferences.deviceFilter.includes(currentDevice)
},
processArtists: (artists) => artists.map((artist) => artist.name).join(", "),
processImages: (images) => {
return {
Expand Down
1 change: 1 addition & 0 deletions translations/de.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"DISPLAY_PRIVATE": "Private Spotify-Sitzung",
"FILTERED_PLAYING": "Nothing is playing in this room.",
"PRODUCT_WARNING": "Das aktuelle Konto hat kein Spotify Premium. Dieses Modul erfordert ein Premium-Konto!",
"CONNECTION_WARNING": "Es gab einen Verbindungsfehler. Verlangsamung des Abfragezyklus von api.spotify/...",
"CONNECTION_ERROR": "Verbindungsfehler bestehen weiterhin. Weitere Verlangsamung des Abfragezyklus. Alte Player-Daten werden ausgeblendet.",
Expand Down
1 change: 1 addition & 0 deletions translations/en.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"DISPLAY_PRIVATE": "Private Spotify session",
"FILTERED_PLAYING": "Nothing is playing in this room.",
"PRODUCT_WARNING": "The current account is not using Spotify Premium. This module requieres a Premium account.",
"CONNECTION_WARNING": "There was a connection error. Slowing the polling of api.spotify/...",
"CONNECTION_ERROR": "Connection errors persists. Slowing the polling more. Hiding old player data.",
Expand Down
1 change: 1 addition & 0 deletions translations/es.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"DISPLAY_PRIVATE": "Sesión de Spotify privada",
"FILTERED_PLAYING": "Nada en reprocucción en este disp.",
"PRODUCT_WARNING": "La cuenta actual de Spotify no es Premium. Este modulo requiere de una cuenta Premium para funcionar.",
"CONNECTION_WARNING": "Hubo un problema de conexión. Ralentizando el polling a api.spotify/...",
"CONNECTION_ERROR": "Los problemas de conexión persisten. Ralentizando más el polling. Ocultando la reprocucción antigua.",
Expand Down
1 change: 1 addition & 0 deletions translations/yourlanguaje.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"DISPLAY_PRIVATE": "Private Spotify session",
"FILTERED_PLAYING": "Nothing is playing in this room.",
"PRODUCT_WARNING": "The current account is not using Spotify Premium. This module requieres a Premium account.",
"CONNECTION_WARNING": "There was a connection error. Slowing the polling of api.spotify/...",
"CONNECTION_ERROR": "Connection errors persists. Slowing the polling more. Hiding old player data.",
Expand Down
5 changes: 4 additions & 1 deletion utils/SpotifyDomBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class SpotifyDomBuilder {
palette_muteddark: "--ONSP-VIBRANT-DARKMUTED",
brand_spotify: "--ONSP-BRANDCOLOR-SPOTIFY",
};
this.changeSubtitleForNotice =
this.config.deviceFilter.length > 0 && this.config.filterNoticeSubtitle ?
"FILTERED_PLAYING" : "NOTHING_PLAYING"
try {
this.animationDefaultDelayFromCSS = Number(
getComputedStyle(this.root)
Expand Down Expand Up @@ -665,7 +668,7 @@ class SpotifyDomBuilder {
);
this.root.style.setProperty(
"--ONSP-INTERNAL-USER-SUBTITLE",
`'${this.translate("NOTHING_PLAYING")}'`,
`'${this.translate(this.changeSubtitleForNotice)}'`,
);
if (!data.image) {
this.root.style.setProperty(
Expand Down
Loading