Skip to content

Instantly share code, notes, and snippets.

@OozoraHaruto
Created July 23, 2020 04:57
Show Gist options
  • Save OozoraHaruto/69443e637a19e4600ae60716dc2b3232 to your computer and use it in GitHub Desktop.
Save OozoraHaruto/69443e637a19e4600ae60716dc2b3232 to your computer and use it in GitHub Desktop.
A simple Node-RED Spotify Dashboard UI

A simple Node-RED Spotify Dashboard UI

Spotify premium subscription is needed for this to work

3 Dashboard Groups

  • Current Playing (refreshes every second
    • See the song that is currently playing (if any)
    • Ability to:
      • Play / Pause
      • Skip to previous / next song
      • Set volume
      • On / Off Shuffle
      • Set Repeat
    • Sends out a MQTT when the song is changed
  • Devices
    • Change the device that is currently playing
    • Manual Refresh (only refreshes automatically when device change is detected)
  • Me
    • View
      • Your playist
      • recommendations
        • Your top 5 artist and tracks are randomly picked to seed the recommendations
      • View editor's pick (Featured playlist)
      • New releases
      • Your top artists that you listen to
      • Your top tracks that you listen to
    • View tracks from
      • Playlists
      • Albums
      • Artists (top tracks)
    • Play tracks

Palattes Needed:

Needed spotify Scopes

Spotify

user-read-playback-state,user-modify-playback-state,user-read-currently-playing,streaming,app-remote-control,playlist-read-collaborative,playlist-read-private,user-library-read,user-top-read,user-read-playback-position,user-read-recently-played

Things to do

  • Install Node-RED
  • Start the server and install the above palattes via the menu
  • Copy everything in the flow.json file below
  • Import into into Node-RED via the menu
  • Create your spotify authentication according to what is needed above
  • Change all the spotify nodes to your authentication
  • Configure or delete the MQTT
  • Deploy the flow
  • Enjoy your dashboard :D
[
{
"id": "11ab4896.0d3b47",
"type": "tab",
"label": "UI Spotify",
"disabled": false,
"info": ""
},
{
"id": "c4292f44.938b2",
"type": "ui_text",
"z": "11ab4896.0d3b47",
"group": "dcc72ee9.a41bf",
"order": 1,
"width": 6,
"height": 3,
"name": "lbl_CurrentPlaying",
"label": "{{msg.song}}",
"format": "{{msg.artist}}",
"layout": "col-center",
"x": 630,
"y": 80,
"wires": []
},
{
"id": "a980396e.e65198",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getMyCurrentPlaybackState",
"x": 460,
"y": 40,
"wires": [
[
"35cc223b.59f87e",
"492aa682.50f7a8",
"4555e371.236ddc"
]
]
},
{
"id": "82492ebf.4069a",
"type": "inject",
"z": "11ab4896.0d3b47",
"name": "Manual Load",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 190,
"y": 120,
"wires": [
[
"a980396e.e65198"
]
]
},
{
"id": "f2956d6a.91b23",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "Not empty",
"func": "var getArtists = global.get(\"GET_ARTISTS\")\nvar repeats = global.get(\"SPOTIFY_REPEATS\")\nvar repeat = repeats.indexOf(msg.payload.repeat_state) + 1\nvar artistStr = getArtists(msg.payload.item.artists)\nvar desc = artistStr === \"\" ? msg.payload.item.name : msg.payload.item.name + \"\\nby \" + artistStr\n\nvar checkGlobal = global.get(\"CHECK_GLOBAL\")\ncheckGlobal(\"futureShuffle\", !msg.payload.shuffle_state)\ncheckGlobal(\"futurePlaying\", !msg.payload.is_playing)\ncheckGlobal(\"futureRepeat\", repeats[repeat == repeats.length ? 0 : repeat])\n\nreturn {\n song: msg.payload.item.name,\n artist: artistStr,\n desc: desc,\n shuffleState: msg.payload.shuffle_state,\n shuffleStateLabel: msg.payload.shuffle_state ? \"On\" : \"Off\",\n repeatState: msg.payload.repeat_state,\n isPlaying: msg.payload.is_playing,\n isPlayingText: msg.payload.is_playing ? \"Pause\" : \"Play\",\n volume: msg.payload.device.volume_percent,\n enabled: true\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 370,
"y": 140,
"wires": [
[
"c4292f44.938b2",
"33132bc5.d2e874",
"75dc1e1.fd8bde",
"b0e60a92.2487a8",
"33dc96f9.a3977a",
"4ee42dc4.fceaf4",
"5142c663.d042d8",
"c4cce512.b175d8",
"5a04c326.be19bc",
"40d8ad67.cb7674"
]
]
},
{
"id": "35cc223b.59f87e",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "Check if empty",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "nempty"
},
{
"t": "empty"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 700,
"y": 40,
"wires": [
[
"f2956d6a.91b23"
],
[
"525bd766.b5a508"
]
]
},
{
"id": "525bd766.b5a508",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "Empty",
"func": "return {\n song: \"No Songs playing\",\n artist: \"Select a device or start playing manually on a device\",\n shuffleStateLabel: \"-\",\n repeatState: \"-\",\n isPlayingText: \"-\",\n volume: 0,\n enabled: false\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 390,
"y": 100,
"wires": [
[
"c4cce512.b175d8",
"33132bc5.d2e874",
"75dc1e1.fd8bde",
"b0e60a92.2487a8",
"33dc96f9.a3977a",
"5a04c326.be19bc",
"c4292f44.938b2",
"4ee42dc4.fceaf4",
"5142c663.d042d8"
]
]
},
{
"id": "c4cce512.b175d8",
"type": "ui_button",
"z": "11ab4896.0d3b47",
"name": "btn_Shuffle",
"group": "dcc72ee9.a41bf",
"order": 2,
"width": 1,
"height": 1,
"passthru": false,
"label": "",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-random",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 610,
"y": 120,
"wires": [
[
"c8288e1c.3549d"
]
],
"outputLabels": [
"topic"
]
},
{
"id": "33132bc5.d2e874",
"type": "ui_button",
"z": "11ab4896.0d3b47",
"name": "btn_Prev",
"group": "dcc72ee9.a41bf",
"order": 3,
"width": 1,
"height": 1,
"passthru": false,
"label": "",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-backward",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 600,
"y": 160,
"wires": [
[
"4355b403.ed437c"
]
]
},
{
"id": "75dc1e1.fd8bde",
"type": "ui_button",
"z": "11ab4896.0d3b47",
"name": "btn_Play",
"group": "dcc72ee9.a41bf",
"order": 4,
"width": 2,
"height": 1,
"passthru": false,
"label": "{{msg.isPlayingText}}",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 600,
"y": 200,
"wires": [
[
"4d986dab.752a04"
]
]
},
{
"id": "b0e60a92.2487a8",
"type": "ui_button",
"z": "11ab4896.0d3b47",
"name": "btn_Next",
"group": "dcc72ee9.a41bf",
"order": 5,
"width": 1,
"height": 1,
"passthru": false,
"label": "",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-forward",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 600,
"y": 240,
"wires": [
[
"ad246bac.466b08"
]
]
},
{
"id": "33dc96f9.a3977a",
"type": "ui_button",
"z": "11ab4896.0d3b47",
"name": "btn_Repeat",
"group": "dcc72ee9.a41bf",
"order": 6,
"width": 1,
"height": 1,
"passthru": false,
"label": "",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-repeat",
"payload": "",
"payloadType": "str",
"topic": "",
"x": 610,
"y": 280,
"wires": [
[
"2f4f56db.f4384a"
]
]
},
{
"id": "4ee42dc4.fceaf4",
"type": "ui_text",
"z": "11ab4896.0d3b47",
"group": "dcc72ee9.a41bf",
"order": 7,
"width": 3,
"height": 1,
"name": "",
"label": "Shuffle",
"format": "{{msg.shuffleStateLabel}}",
"layout": "row-spread",
"x": 590,
"y": 320,
"wires": []
},
{
"id": "5142c663.d042d8",
"type": "ui_text",
"z": "11ab4896.0d3b47",
"group": "dcc72ee9.a41bf",
"order": 8,
"width": 3,
"height": 1,
"name": "",
"label": "Repeat",
"format": "{{msg.repeatState}}",
"layout": "row-spread",
"x": 600,
"y": 360,
"wires": []
},
{
"id": "c0b4a9fc.ab8578",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "setShuffle",
"x": 1000,
"y": 120,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "c8288e1c.3549d",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParams",
"func": "\nreturn {\n params: [{\n state: global.get(\"futureShuffle\")\n }]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 810,
"y": 120,
"wires": [
[
"c0b4a9fc.ab8578"
]
]
},
{
"id": "7b596e7c.77fbd",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "success?",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "nnull"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 1180,
"y": 200,
"wires": [
[
"a980396e.e65198"
],
[
"346a99f9.a7f626"
]
]
},
{
"id": "346a99f9.a7f626",
"type": "ui_toast",
"z": "11ab4896.0d3b47",
"position": "bottom right",
"displayTime": "10",
"highlight": "",
"sendall": true,
"outputs": 0,
"ok": "OK",
"cancel": "",
"raw": false,
"topic": "Failed to update",
"name": "notify failed",
"x": 1330,
"y": 200,
"wires": []
},
{
"id": "4355b403.ed437c",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "skipToPrevious",
"x": 820,
"y": 160,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "ad246bac.466b08",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "skipToNext",
"x": 810,
"y": 240,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "4d986dab.752a04",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "",
"property": "futurePlaying",
"propertyType": "global",
"rules": [
{
"t": "true"
},
{
"t": "false"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 790,
"y": 200,
"wires": [
[
"4098eaa8.936fa4"
],
[
"2aa3004f.6ecc4"
]
]
},
{
"id": "4098eaa8.936fa4",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "play",
"x": 1010,
"y": 180,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "2aa3004f.6ecc4",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "pause",
"x": 1010,
"y": 220,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "2f4f56db.f4384a",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParams",
"func": "\nreturn {\n params: [{\n state: global.get(\"futureRepeat\")\n }]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 810,
"y": 280,
"wires": [
[
"41afaee4.cf6b4"
]
]
},
{
"id": "41afaee4.cf6b4",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "setRepeat",
"x": 990,
"y": 280,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "8fd4fd25.3857e",
"type": "hidden-ui-load",
"z": "11ab4896.0d3b47",
"group": "dcc72ee9.a41bf",
"order": 0,
"name": "",
"x": 200,
"y": 40,
"wires": [
[
"a980396e.e65198",
"f0578e8a.64225",
"f1179638.4bde68",
"9335eb90.88b5b8",
"f2fc78b3.e3dea8",
"a9224b3f.06f0f8",
"92f8049d.02a9a8"
]
]
},
{
"id": "f0578e8a.64225",
"type": "trigger",
"z": "11ab4896.0d3b47",
"name": "repeat 1s",
"op1": "1",
"op2": "0",
"op1type": "str",
"op2type": "str",
"duration": "-1",
"extend": false,
"units": "s",
"reset": "",
"bytopic": "all",
"topic": "topic",
"outputs": 1,
"x": 200,
"y": 80,
"wires": [
[
"a980396e.e65198"
]
]
},
{
"id": "f1179638.4bde68",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getMyDevices",
"x": 420,
"y": 460,
"wires": [
[
"1b391db9.b03b02"
]
]
},
{
"id": "492aa682.50f7a8",
"type": "debug",
"z": "11ab4896.0d3b47",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 990,
"y": 40,
"wires": []
},
{
"id": "4bd5d36b.60457c",
"type": "ui_list",
"z": "11ab4896.0d3b47",
"group": "1ed634dd.8f160b",
"name": "",
"order": 2,
"width": "6",
"height": "4",
"lineType": "three",
"actionType": "click",
"allowHTML": false,
"outputs": 1,
"topic": "",
"x": 590,
"y": 500,
"wires": [
[
"df40a6e9.7b2bb8"
]
]
},
{
"id": "1b391db9.b03b02",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "",
"func": "var devices = []\nvar iconsDevices = global.get(\"SPOTIFY_ICON_DEVICES\")\nmsg.payload.devices.forEach(device => {\n var description = \"\";\n if(device.is_restricted){\n description = \"Cannot connect\"\n }else if(device.is_active){\n description = \"Current device\"\n global.set(\"currentDevice\", device.id)\n }\n \n devices.push({\n id: device.id,\n title: device.name,\n description: description,\n icon_name: iconsDevices[device.type]\n })\n})\nreturn {\n payload: devices\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 380,
"y": 500,
"wires": [
[
"4bd5d36b.60457c"
]
]
},
{
"id": "b0fe37f7.d009d8",
"type": "ui_button",
"z": "11ab4896.0d3b47",
"name": "btn_refresh",
"group": "1ed634dd.8f160b",
"order": 1,
"width": 0,
"height": 0,
"passthru": false,
"label": "",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-refresh",
"payload": "1",
"payloadType": "str",
"topic": "",
"x": 190,
"y": 460,
"wires": [
[
"f1179638.4bde68"
]
]
},
{
"id": "528923c1.f87d0c",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "changeDevice",
"auth": "",
"api": "transferMyPlayback",
"x": 980,
"y": 500,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "df40a6e9.7b2bb8",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParams",
"func": "\nreturn {\n params: [{\n deviceIds: [msg.payload.id],\n play: true\n }]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 810,
"y": 500,
"wires": [
[
"528923c1.f87d0c"
]
]
},
{
"id": "4555e371.236ddc",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "Check Device Change",
"property": "payload.device.id",
"propertyType": "msg",
"rules": [
{
"t": "neq",
"v": "currentDevice",
"vt": "global"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 340,
"y": 180,
"wires": [
[
"f1179638.4bde68"
]
]
},
{
"id": "cc3b1f20.469b3",
"type": "ui_slider",
"z": "11ab4896.0d3b47",
"name": "",
"label": "Volume",
"tooltip": "",
"group": "dcc72ee9.a41bf",
"order": 9,
"width": 6,
"height": 1,
"passthru": false,
"outs": "end",
"topic": "",
"min": 0,
"max": "100",
"step": 1,
"x": 600,
"y": 400,
"wires": [
[
"9e70f325.fa376"
]
]
},
{
"id": "5a04c326.be19bc",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "",
"func": "return {\n payload: msg.volume,\n enabled: msg.enabled\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 380,
"y": 400,
"wires": [
[
"cc3b1f20.469b3"
]
]
},
{
"id": "157d2595.2742da",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "setVolume",
"x": 990,
"y": 400,
"wires": [
[
"7b596e7c.77fbd"
]
]
},
{
"id": "9e70f325.fa376",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParams",
"func": "\nreturn {\n params: [\n msg.payload\n ]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 810,
"y": 400,
"wires": [
[
"157d2595.2742da"
]
]
},
{
"id": "555040a1.e29bf",
"type": "ui_dropdown",
"z": "11ab4896.0d3b47",
"name": "",
"label": "",
"tooltip": "",
"place": "Select option",
"group": "b722016b.b016c",
"order": 1,
"width": 0,
"height": 0,
"passthru": true,
"multiple": false,
"options": [
{
"label": "Playlist",
"value": "playlist",
"type": "str"
},
{
"label": "Recommendations",
"value": "recommendations",
"type": "str"
},
{
"label": "Featured Playlists",
"value": "featuredPlaylist",
"type": "str"
},
{
"label": "New Releases",
"value": "newReleases",
"type": "str"
},
{
"label": "Top Artists",
"value": "topArtist",
"type": "str"
},
{
"label": "Top Tracks",
"value": "topTrack",
"type": "str"
}
],
"payload": "",
"topic": "",
"x": 610,
"y": 560,
"wires": [
[
"90b3afd7.a34c6"
]
]
},
{
"id": "9335eb90.88b5b8",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "Set Globals",
"func": "// Functions\nconst checkGlobal = (keyword, checkData) =>{\n if(global.get(keyword) != checkData){\n global.set(keyword, checkData)\n }\n}\nconst getTop5Ids = results =>{\n var maxId = results.length\n var ids = []\n if(maxId > 5){\n maxId = 5\n }\n for(var i = 0; i < maxId; i++){\n ids.push(results[i].id)\n }\n return ids\n}\nconst getArtists = artists =>{\n var artistsArr = []\n artists.forEach(artist => artistsArr.push(artist.name))\n return artistsArr.join(\", \")\n}\n\n// Reset Globals\nglobal.set(\"futureShuffle\", undefined);\nglobal.set(\"futurePlaying\", undefined);\nglobal.set(\"futureRepeat\", undefined);\nglobal.set(\"currentDevice\", undefined);\nglobal.set(\"currentSong\", undefined);\nglobal.set(\"playAll\", undefined);\n// console.log(global.keys())\n\n// Set Globals\nglobal.set(\"SPOTIFY_REPEATS\", [\"track\", \"context\", \"off\"])\nglobal.set(\"SPOTIFY_ICON_DEVICES\", {\n \"Computer\" : \"desktop_mac\",\n \"Tablet\" : \"tablet_mac\",\n \"Smartphone\" : \"phone_iphone\",\n \"Speaker\" : \"speaker\",\n \"TV\" : \"tv\",\n \"AVR\" : \"devices_other\",\n \"STB\" : \"tv\",\n \"AudioDongle\" : \"headset\",\n \"GameConsole\" : \"vidiogame_asset\",\n \"CastVideo\" : \"phonelink_off\",\n \"CastAudio\" : \"phonelink_off\",\n \"Automobile\" : \"directions_car\",\n \"Unknown\" : \"devices_other\",\n})\nglobal.set(\"CHECK_GLOBAL\", checkGlobal)\nglobal.set(\"GET_TOP_5_IDS\", getTop5Ids)\nglobal.set(\"GET_ARTISTS\", getArtists)",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 150,
"y": 160,
"wires": [
[]
]
},
{
"id": "20d6caa0.5e2326",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getUserPlaylists",
"x": 420,
"y": 680,
"wires": [
[
"ebee499f.0807c8"
]
]
},
{
"id": "c60d342a.d3a8f8",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getFeaturedPlaylists",
"x": 440,
"y": 720,
"wires": [
[
"ebee499f.0807c8"
]
]
},
{
"id": "f2fc78b3.e3dea8",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "",
"func": "return {\n payload: global.get(\"SPOTIFY_ME\") ? global.get(\"SPOTIFY_ME\") : \"playlist\"\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 380,
"y": 560,
"wires": [
[
"555040a1.e29bf"
]
]
},
{
"id": "bf53887.3ce9178",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "playlist",
"vt": "str"
},
{
"t": "eq",
"v": "featuredPlaylist",
"vt": "str"
},
{
"t": "eq",
"v": "newReleases",
"vt": "str"
},
{
"t": "eq",
"v": "recommendations",
"vt": "str"
},
{
"t": "eq",
"v": "topArtist",
"vt": "str"
},
{
"t": "eq",
"v": "topTrack",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 6,
"x": 210,
"y": 700,
"wires": [
[
"20d6caa0.5e2326"
],
[
"c60d342a.d3a8f8"
],
[
"685a5834.233b98"
],
[
"9705362d.74bef8"
],
[
"2a4a995.569cc66"
],
[
"e33270e1.6dfdd"
]
]
},
{
"id": "1c2802f1.1cf35d",
"type": "ui_toast",
"z": "11ab4896.0d3b47",
"position": "bottom right",
"displayTime": "10",
"highlight": "",
"sendall": true,
"outputs": 0,
"ok": "OK",
"cancel": "",
"raw": false,
"topic": "Failed to update",
"name": "notify failed",
"x": 190,
"y": 980,
"wires": []
},
{
"id": "737ab744.52a668",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "",
"func": "var replies = [];\nvar items = [];\n\nif(msg.payload.items){\n replies = msg.payload.items\n}else if (msg.payload.playlists){\n replies = msg.payload.playlists.items\n}else if (msg.payload.albums){\n replies = msg.payload.albums.items\n}else if (msg.payload.tracks){\n replies = msg.payload.tracks\n}\n\nreplies.forEach(reply =>{\n var item = reply.name ? reply : reply.track\n var temp = {\n id: item.id,\n title: item.name,\n description: item.description || \"\",\n // image: item.images.length !== 0 ? item.images[0].url : \"\",\n type: item.type,\n uri: item.uri\n }\n if(item.type !== \"track\"){\n //set tracks\n if(temp.type == \"album\"){\n temp.tracksTotal = item.total_tracks\n }else if (item.tracks){\n temp.tracksTotal = item.tracks.total\n }else{\n temp.tracksTotal = 0\n }\n \n //set descriptions\n if(temp.tracksTotal !== 0){\n if(temp.description !== \"\"){\n temp.description += \"<br />\"\n }\n temp.description += (temp.tracksTotal + \" tracks\")\n }\n \n //set icon\n if(item.images.length !== 0){\n temp.icon = item.images[0].url\n }else{\n switch(item.type){\n case \"album\": temp.icon_name = \"album\"; break;\n case \"playlist\": temp.icon_name = \"playlist_play\"; break;\n case \"playlist\": temp.icon_name = \"fa-user\"; break;\n }\n }\n }else{\n var getArtists = global.get(\"GET_ARTISTS\")\n //set icon\n if(item.album){\n console.log(\"In item.ablum\")\n if(item.album.images.length !== 0){\n temp.icon = item.album.images[0].url\n }else{\n temp.icon_name = \"audiotrack\";\n }\n }else{\n temp.icon_name = \"audiotrack\";\n }\n \n //set descriptions\n temp.description = getArtists(item.artists)\n if(item.is_local){\n if(temp.description !== \"\"){\n temp.description += \"<br />\";\n }\n temp.description += \"* Unplayable on some devices\";\n }\n }\n items.push(temp)\n})\n\nreturn {\n payload: items\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 380,
"y": 940,
"wires": [
[
"fe4abcc5.9af56",
"68008dd9.e843b4"
]
]
},
{
"id": "fe4abcc5.9af56",
"type": "ui_list",
"z": "11ab4896.0d3b47",
"group": "b722016b.b016c",
"name": "",
"order": 6,
"width": "6",
"height": "13",
"lineType": "three",
"actionType": "click",
"allowHTML": true,
"outputs": 1,
"topic": "",
"x": 570,
"y": 1000,
"wires": [
[
"e5091e7c.c8994"
]
]
},
{
"id": "685a5834.233b98",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getNewReleases",
"x": 430,
"y": 760,
"wires": [
[
"ebee499f.0807c8"
]
]
},
{
"id": "a4bb066f.31c6e8",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getRecommendations",
"x": 1120,
"y": 800,
"wires": [
[
"ebee499f.0807c8"
]
]
},
{
"id": "9705362d.74bef8",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getMyTopArtists",
"x": 420,
"y": 800,
"wires": [
[
"76683a09.6c0cb4"
]
]
},
{
"id": "76683a09.6c0cb4",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setFavArtists",
"func": "var getTop5Ids = global.get(\"GET_TOP_5_IDS\")\nflow.set(\"favArtists\", getTop5Ids(msg.payload.items))\n\nreturn {\n payload: 1\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 590,
"y": 800,
"wires": [
[
"fb123e7e.6c0b4"
]
]
},
{
"id": "fb123e7e.6c0b4",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getMyTopTracks",
"x": 760,
"y": 800,
"wires": [
[
"ae2a5dd7.240fe"
]
]
},
{
"id": "ae2a5dd7.240fe",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setFavArtists",
"func": "var getTop5Ids = global.get(\"GET_TOP_5_IDS\")\nflow.set(\"favTracks\", getTop5Ids(msg.payload.items))\nvar list = flow.get(\"favTracks\").concat(flow.get(\"favArtists\"))\nvar tmpList = []\nvar artists = []\nvar tracks = []\n\ndo{\n var idx = Math.floor(Math.random() * 10)\n var item = list[idx]\n \n if(!tmpList.indexOf(item) !== -1){\n tmpList.push(item)\n }\n}while(tmpList.length != 5)\n\ntmpList.forEach(item =>{\n if(flow.get(\"favTracks\").indexOf(item) != -1){\n tracks.push(item)\n }else{\n artists.push(item)\n }\n})\n\n\nreturn {\n params: [{\n limit: 100,\n seed_artists: artists,\n seed_tracks: tracks\n }]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 930,
"y": 800,
"wires": [
[
"a4bb066f.31c6e8"
]
]
},
{
"id": "ebee499f.0807c8",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "success?",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "nnull"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 200,
"y": 940,
"wires": [
[
"737ab744.52a668"
],
[
"1c2802f1.1cf35d"
]
]
},
{
"id": "62539f07.b3fb7",
"type": "ui_ui-button",
"z": "11ab4896.0d3b47",
"action": "click",
"actionType": "str",
"name": "btnPlayAll",
"group": "b722016b.b016c",
"order": 3,
"width": "3",
"height": "1",
"passthru": false,
"label": "Play All",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-play",
"x": 600,
"y": 640,
"wires": [
[
"1abb8d93.675cf2"
]
]
},
{
"id": "e2cabfa9.1035a",
"type": "ui_ui-button",
"z": "11ab4896.0d3b47",
"action": "click",
"actionType": "str",
"name": "btnBack",
"group": "b722016b.b016c",
"order": 2,
"width": "3",
"height": "1",
"passthru": false,
"label": "Back",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "fa-chevron-left",
"x": 600,
"y": 600,
"wires": [
[
"92f8049d.02a9a8",
"a9224b3f.06f0f8",
"f2fc78b3.e3dea8"
]
]
},
{
"id": "a9224b3f.06f0f8",
"type": "hidden-ui-action",
"z": "11ab4896.0d3b47",
"action": "disable",
"actionType": "str",
"write": "1",
"writeType": "num",
"group": "dcc72ee9.a41bf",
"order": 4,
"target": "62539f07.b3fb7",
"passthru": false,
"name": "Disable PlayAll",
"x": 140,
"y": 200,
"wires": [
[]
]
},
{
"id": "92f8049d.02a9a8",
"type": "hidden-ui-action",
"z": "11ab4896.0d3b47",
"action": "disable",
"actionType": "str",
"write": "1",
"writeType": "num",
"group": "dcc72ee9.a41bf",
"order": 3,
"target": "e2cabfa9.1035a",
"passthru": false,
"name": "Disable Back",
"x": 150,
"y": 240,
"wires": [
[]
]
},
{
"id": "40d8ad67.cb7674",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "Check Song Change",
"property": "currentSong",
"propertyType": "global",
"rules": [
{
"t": "neq",
"v": "desc",
"vt": "msg"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 340,
"y": 220,
"wires": [
[
"38a1de51.e638b2"
]
]
},
{
"id": "957040ca.70ceb",
"type": "mqtt out",
"z": "11ab4896.0d3b47",
"name": "",
"topic": "Spotify Song Changed",
"qos": "",
"retain": "",
"broker": "",
"x": 340,
"y": 300,
"wires": []
},
{
"id": "38a1de51.e638b2",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "",
"func": "global.set(\"currentSong\", msg.desc)\n// console.log(msg.desc)\n\nreturn {\n payload: msg.desc +\"=:=Spotify.png\"\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 380,
"y": 260,
"wires": [
[
"957040ca.70ceb"
]
]
},
{
"id": "274addac.f69762",
"type": "hidden-ui-action",
"z": "11ab4896.0d3b47",
"action": "enable",
"actionType": "str",
"write": "1",
"writeType": "num",
"group": "dcc72ee9.a41bf",
"order": 4,
"target": "62539f07.b3fb7",
"passthru": false,
"name": "Enable PlayAll",
"x": 800,
"y": 620,
"wires": [
[]
]
},
{
"id": "68008dd9.e843b4",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "Check Tracks",
"property": "payload[0].type",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "track",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 600,
"y": 940,
"wires": [
[
"274addac.f69762",
"ad6a8672.ed7f18"
],
[
"a9224b3f.06f0f8"
]
]
},
{
"id": "ad6a8672.ed7f18",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "Set playAll var",
"func": "var playback = []\nif(msg.payload[0].uri.split(\":\")[1] == \"track\"){\n msg.payload.forEach(song =>{\n playback.push(song.uri)\n })\n}else{\n playback = msg.payload[0].uri\n}\n// console.log(\"playback\", playback)\n\nglobal.set(\"playAll\", playback);",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 800,
"y": 660,
"wires": [
[]
]
},
{
"id": "e5091e7c.c8994",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "Check Type",
"property": "payload.type",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "track",
"vt": "str"
},
{
"t": "eq",
"v": "playlist",
"vt": "str"
},
{
"t": "eq",
"v": "album",
"vt": "str"
},
{
"t": "eq",
"v": "artist",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 4,
"x": 730,
"y": 1000,
"wires": [
[
"1abb8d93.675cf2"
],
[
"ca9e534e.2e1a4"
],
[
"210e6f32.2971e"
],
[
"a8ca957.cfcc568"
]
]
},
{
"id": "1e4d397.ee71dc7",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParams",
"func": "var call = {}\n\nif(Array.isArray(global.get(\"playAll\"))){\n call.uris = global.get(\"playAll\")\n}else{\n call.context_uri = global.get(\"playAll\")\n}\n// call.offset = msg.payload ? { uri: msg.payload.uri } : {position: 0}\nif(msg.payload){\n call.offset = { uri: msg.payload.uri }\n}\n\nreturn {\n params: [call]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1010,
"y": 660,
"wires": [
[
"4098eaa8.936fa4"
]
]
},
{
"id": "ab450d4d.3b5fc",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getPlaylistTracks",
"x": 1110,
"y": 980,
"wires": [
[
"f7856b8e.20bc38"
]
]
},
{
"id": "ca9e534e.2e1a4",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParam",
"func": "return {\n params: [\n msg.payload.id\n ]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 920,
"y": 980,
"wires": [
[
"ab450d4d.3b5fc"
]
]
},
{
"id": "210e6f32.2971e",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParam",
"func": "return {\n params: [\n msg.payload.id,\n {\n limit: 50\n }\n ]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 920,
"y": 1020,
"wires": [
[
"15aa529d.631bfd"
]
]
},
{
"id": "15aa529d.631bfd",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getAlbumTracks",
"x": 1100,
"y": 1020,
"wires": [
[
"f7856b8e.20bc38"
]
]
},
{
"id": "a122d57.6283528",
"type": "hidden-ui-action",
"z": "11ab4896.0d3b47",
"action": "enable",
"actionType": "str",
"write": "1",
"writeType": "num",
"group": "dcc72ee9.a41bf",
"order": 4,
"target": "e2cabfa9.1035a",
"passthru": false,
"name": "Enable Back",
"x": 1010,
"y": 740,
"wires": [
[]
]
},
{
"id": "f7856b8e.20bc38",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "success?",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "nnull"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 820,
"y": 740,
"wires": [
[
"737ab744.52a668",
"a122d57.6283528"
],
[
"1c2802f1.1cf35d"
]
]
},
{
"id": "90b3afd7.a34c6",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setSPOTIFY_ME",
"func": "global.set(\"SPOTIFY_ME\", msg.payload)\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 170,
"y": 620,
"wires": [
[
"bf53887.3ce9178",
"a9224b3f.06f0f8",
"92f8049d.02a9a8"
]
]
},
{
"id": "1abb8d93.675cf2",
"type": "switch",
"z": "11ab4896.0d3b47",
"name": "currentlyPlaying?",
"property": "currentDevice",
"propertyType": "global",
"rules": [
{
"t": "nnull"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 790,
"y": 700,
"wires": [
[
"1e4d397.ee71dc7"
],
[
"bfef7e33.31d63"
]
]
},
{
"id": "bfef7e33.31d63",
"type": "ui_toast",
"z": "11ab4896.0d3b47",
"position": "dialog",
"displayTime": "10",
"highlight": "",
"sendall": false,
"outputs": 1,
"ok": "OK",
"cancel": "",
"raw": false,
"topic": "Select a device to play on and try again",
"name": "notify impossible",
"x": 1030,
"y": 700,
"wires": [
[]
]
},
{
"id": "2a4a995.569cc66",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getMyTopArtists",
"x": 420,
"y": 840,
"wires": [
[
"ebee499f.0807c8"
]
]
},
{
"id": "e33270e1.6dfdd",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getMyTopTracks",
"x": 420,
"y": 880,
"wires": [
[
"ebee499f.0807c8"
]
]
},
{
"id": "13b0439c.cb8abc",
"type": "spotify",
"z": "11ab4896.0d3b47",
"name": "",
"auth": "",
"api": "getArtistTopTracks",
"x": 1110,
"y": 1060,
"wires": [
[
"f7856b8e.20bc38"
]
]
},
{
"id": "a8ca957.cfcc568",
"type": "function",
"z": "11ab4896.0d3b47",
"name": "setParam",
"func": "return {\n params: [\n msg.payload.id,\n \"from_token\"\n ]\n};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 920,
"y": 1060,
"wires": [
[
"13b0439c.cb8abc"
]
]
},
{
"id": "dcc72ee9.a41bf",
"type": "ui_group",
"z": "",
"name": "Current Playing",
"tab": "dc34a0bf.9704b",
"order": 1,
"disp": false,
"width": "6",
"collapse": false
},
{
"id": "1ed634dd.8f160b",
"type": "ui_group",
"z": "",
"name": "Devices",
"tab": "dc34a0bf.9704b",
"order": 2,
"disp": true,
"width": "6",
"collapse": true
},
{
"id": "b722016b.b016c",
"type": "ui_group",
"z": "",
"name": "Me",
"tab": "dc34a0bf.9704b",
"order": 3,
"disp": true,
"width": "6",
"collapse": true
},
{
"id": "dc34a0bf.9704b",
"type": "ui_tab",
"z": "",
"name": "Spotify",
"icon": "fa-spotify",
"order": 1,
"disabled": false,
"hidden": false
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment