Sonos Api random playlists and random radiostations

I made a homeyscript to play random radiostations set as favorite on Sonos and play random Spotify playlists. The script contains 14 days of music. You can adjust the radiostations and playlists.

Start the script once a day and a new radiostation or playlist will be played on your Sonos device. After two weeks the script will automatically refresh. The playing order will see to it that there will be no duplicate radiostations in a row, and this will also happen for the playlists.

You have to install the Sonos API google for jishi/node-sonos-http-api. On a server with Dicker You have to search for the chrisns-docker-node-sonos-http-api.

Add your local server’s ipadres and portnumberPrefix in this script

Copy the next script and run this once. You can delete is afterwards

global.set(‘radioToday’, []);
global.set(‘radioUpdate’, true);
global.set(‘radio’,[]);

You can obtain the playlistid like this:



copy the next script and run. You can adjust your radiostations, playlist and radionames @ the remarks

// Script for randomly playing your favorite Sonos radiostations and Spotify playlists
// Using a Server with the Sonos Api 

// Add your Server's Ipadres and PortnumberPrefix 
var ipAdres = '192.168.1.2';
var portNumber = '5005';

// Do not adjust 
var radioPrefix = 'http://' + ipAdres + ':' + portNumber + '/woonkamer/favorite/';
var playListPrefix = 'http://'+ ipAdres + ':'+ portNumber + '/woonkamer/spotify/now/spotify:user:spotify:playlist:';

//In your Sonos app, from Sonos(not Homey) you need to add your personal radiostations as favorite. 
//There are three variables for playlists. Therefore the variables radio12, radio13 and radio14 may not
//been altered. 

//To add your playlists you can add 17 playlist at //PlayList. Search for the ID of your playlist in your Spotify App(not Homey) and paste this ID at //PlayList between the quotes
//Make a new script and enter the following: global.set('radio', []); global.set('radioToday',[]);global.set('radioUpdate', true), run this script and delete this script.

//Radiostations=> Add the exact name of your favorite Radiostation between the quotes(scase sensitive). It is possible to delete some radiostations. But do not delete Radio10, Radio11, Radio12.
var radio1 = radioPrefix + 'Ibiza - HD';
var radio2 = radioPrefix + 'Deep Radio';
var radio3 = radioPrefix + 'Dance Radio Amsterdam';
var radio4 = radioPrefix + 'Dance FM';
var radio5 = radioPrefix + 'Deep House Ibiza';
var radio6 = radioPrefix + 'Deep Radio';
var radio7 = radioPrefix + 'Radio 538 Non-stop';
var radio8 = radioPrefix + 'Deep Dance Radio';
var radio9 = radioPrefix + 'Sky Radio - HD';
var radio10 = radioPrefix + 'Slam! Non Stop';
var radio11 = radioPrefix + 'Disco Classic Radio';
var radio12 = 'play1';//Do not adjust this variable
var radio13 = 'play2';//Do not adjust this variable
var radio14 = 'play3';//Do not adjust this variable

var radio =[radio1,radio2,radio3,radio4,radio5,radio6,radio7,radio8,radio9,radio10,radio11,radio12,radio13,radio14];

//Playlist => Add the ID of your Spotify playlist between the quotes. For your own needs you can add the 
//name of the playlist after the //. It is possible to delete some playlistid's.
var playListId1 = '1C5F8dA3nWRN46u6lCehqm?si=67RdCbXtSG27gx6C7qP2Sw';//Deep Delight Part 2
var playListId2 = '1QdAD45sKZQwptkm4VeKmO?si=_5P2-G9-SZG91WsNHt0f4g';//360 Dance Part 2
var playListId3 = '4YKqPMOlV5JJK6XVKKdWJ9?si=SL7iH53eSNu-PnsZJIcr6A';//Deep House Part 2
var playListId4 = '7jzMzltNsYhaI5Xfkxe9If?si=IwDTD4ylQJC9c5JWxEUXQw';//Massive Pop Remixes Part 1
var playListId5 = '5sInx9KNxVqnONg9EsIptX?si=8T0QWluxSDqI3bClrf0OOQ';//Dance Classics Part 1
var playListId6 = '0NhMKI95ujIjriBaRXrIBs?si=pG_J4OXGTz6mhN_kG1mvMg';//Dance Pop Remixes Part 1
var playListId7 = '1s4YUBb95LaWazpgvNGzAu?si=35wEzzqcQIKAgSZq7bkEaA';//Deep House Relax Part 3 
var playListId8 = '60HqFyCYzr6dxr4OMxDtS7?si=x7Oa5bNBQXy4DQlC2COLaw';//Truly Deeply House Part 1
var playListId9 = '00JuraVC5HSlXCLpYJ4RQx?si=LJFWf4UoQ-2DtayVAGb26g';//360 Dance Part 1
var playListId10 = '0C66rsP0YemHrh3dUhSszt?si=gdtcDlzURLWQVZCKi8Evkw';//Deep House Relax Part 2
var playListId11 = '4Vaus40H2m6gkwNqhzzril?si=6y9qg0HxQAqfB_B3bhfeIQ';//Deep Delight Part 1
var playListId12 = '7kS4ICEIagMdVKUMAe2Hy1?si=CazM4dkSQLq-0wJ_IaiJDw';//Deep House Part 3
var playListId13 = '7fwbNi5Be9Jh2ljr9b8Z34?si=uyJ4egMZQHW1r2YmyAhGjA';//Truly Deeply House 2
var playListId14 = '28MJ5Ws6Hw7K3sM0buLxvS?si=sR9304GXTzikRt1n3so-MQ';//Marcels Favorieten 2017
var playListId15 = '4oH8GC0TMvQGlTXlj3luUq?si=RnmzYP4YRCWSPa9ptJTuRA';//Deep House Relax Part 1
var playListId16 = '4g1z40nOzcPytHV5DvWpvB?si=GVjxQsb6RTyA5CB72mjSLQ';//Deep House Relax 4
var playListId17 = '7GQS3BcOeogh8wKEeA3fN8?si=taswh15eRZuXmFAkyn6IfQ';//12inch Classics Part 1

var playListId = [playListId1.substring(0,22),playListId2.substring(0,22),playListId3.substring(0,22),playListId4.substring(0,22),playListId5.substring(0,22),playListId6.substring(0,22),playListId7.substring(0,22),playListId8.substring(0,22),playListId9.substring(0,22),playListId10.substring(0,22),playListId11.substring(0,22),playListId12.substring(0,22),playListId13.substring(0,22),playListId14.substring(0,22),playListId15.substring(0,22),playListId16.substring(0,22),playListId17.substring(0,22)];

global.set('playListId',playListId)

//PlaylistNames => Add the Name as you want to get presented of your Spotify playlist between the quotes. 
var playListName1 = 'Deep Delight Part 2';
var playListName2 = '360 Dance Part 2';
var playListName3 = 'Deep House Part 2';
var playListName4 = 'Massive Pop Remixes Part 1';
var playListName5 = 'Dance Classics Part 1';
var playListName6 = 'Dance Pop Remixes Part 1';
var playListName7 = 'Deep House Relax 3';
var playListName8 = 'Truly Deeply House Part 1';
var playListName9 = '360 Dance Part 1';
var playListName10 = 'Deep House Relax 2';
var playListName11 = 'Deep Delight Part 1';
var playListName12 = 'Deep House Part 3';
var playListName13 = 'Truly Deeply House 2';
var playListName14 = 'Marcels Favorieten 2017';
var playListName15 = 'Deep House Relax Part 1';
var playListName16 = 'Deep House Relax 4';
var playListName17 = '12inch Classics Part 1';

var playListName = [playListName1,playListName2,playListName3,playListName4,playListName5,playListName6,playListName7,playListName8,playListName9,playListName10,playListName11,playListName12,playListName13,playListName14,playListName15,playListName16,playListName17]

global.set('playListName',playListName)

//Do not change the next variables
var playList1 = playListPrefix + playListId[0];//Deep Delight Part 2
var playList2 = playListPrefix + playListId[1];//360 Dance Part 2
var playList3 = playListPrefix + playListId[2];//Deep House Part 2
var playList4 = playListPrefix + playListId[3];//Massive Pop Remixes Part 1
var playList5 = playListPrefix + playListId[4];//Dance Classics Part 1
var playList6 = playListPrefix + playListId[5];//Dance Pop Remixes Part 1
var playList7 = playListPrefix + playListId[6];//Deep House Relax Part 3 
var playList8 = playListPrefix + playListId[7];//Truly Deeply House Part 1
var playList9 = playListPrefix + playListId[8];//360 Dance Part 1
var playList10 = playListPrefix + playListId[9];//Deep House Relax Part 2
var playList11 = playListPrefix + playListId[10];//Deep Delight Part 1
var playList12 = playListPrefix + playListId[11];//Deep House Part 3
var playList13 = playListPrefix + playListId[12];//Truly Deeply House 2
var playList14 = playListPrefix + playListId[13];//Marcels Favorieten 2017
var playList15 = playListPrefix + playListId[14];//Deep House Relax Part 1
var playList16 = playListPrefix + playListId[15];//Deep House Relax 4
var playList17 = playListPrefix + playListId[16];//12inch Classics Part 1

var playList = [playList1,playList2,playList3,playList4,playList5,playList6,playList7,playList8,playList9,playList10,playList11,playList12,playList13,playList14,playList15,playList16,playList17]

//Logic variable radioUpdate
var radioUpdate = global.get('radioUpdate');
console.log('0 radioUpdate is: '+radioUpdate);

if (radioUpdate === false)
{
var temp = global.get('radio');
console.log('1 radio list is: ' +temp)
temp.shift();
global.set('radio', temp);
var radioToday = temp[0];
//Logic variable radioToday
global.set('radioToday', radioToday);
global.set('radioUpdate', true);

if (radioToday.substring(0, radioPrefix.length) === radioPrefix)
{
var title = radioToday.split('/').pop();
console.log('2 radioToday.substring(0,'+radioPrefix.length +') is' +radioToday.substring(0, radioPrefix.length));
console.log('3 radioPrefix is: '+radioPrefix);
console.log('4 title is :' +title);
global.set('title', title);
}

count = 0
if (radioToday.substring(0, playListPrefix.length) === playListPrefix)
{
while(count <= playListId.length -1) 
{
if (radioToday.substring(radioToday.length - 20) === playListId[count].substring(0,20))
var title = playListName[count];
console.log('5 title is: '+title);
count++
}
}

if (radioToday === 'run sonos script again')
{
var temp = new Array();
while (playList.length) 
{
var nummer = playList.length.toString();
console.log('6 nummer is:' +nummer);
var randomIndex = Math.floor(Math.random() * (playList.length));
console.log('7 randomIndex is:' +randomIndex);
var randomNumber = playList.splice(randomIndex, 1)[0];
console.log('8 randomNumber is:' +randomNumber);
temp.splice(randomIndex, 0, randomNumber );
console.log('9 temp is: '+temp);
global.set('play', temp);
}

var temp = new Array();
while (radio.length) 
{
var nummer = radio.length.toString();
console.log('10 nummer is:' +nummer);
var randomIndex = Math.floor(Math.random() * (radio.length));
console.log('11 randomIndex is:' +randomIndex);
var randomNumber = radio.splice(randomIndex, 1)[0];
console.log('12 randomNumber is:' +randomNumber);
temp.splice(randomIndex, 0, randomNumber );
console.log('13 temp is: '+temp);
}

var dupIndexes = new Set();
let i = 0;
while(i < temp.length - 1){
if ((temp[i] === temp[i + 1]) && (temp[i + 1] != temp.length - 1 ) || (temp[i].substring(0,77) === temp[i + 1].substring(0,77)) && (temp[i + 1] != temp.length - 1 ))
{
var duplicate = temp[i]
console.log('14 duplicate is: '+duplicate);
var replace = temp[i + 2];
console.log('15 replace is: '+replace);
temp.splice(i + 1, 1, replace);
temp.splice(i + 2, 1, duplicate);
}

if ((temp[i] === temp[i + 1]) && (temp[i] === 13 ))
{
var duplicate = temp[i];
console.log('16 duplicate is: '+duplicate);
var replace = temp[0];
console.log('17 replace is: '+replace);
temp.splice(i + 1, 1, replace);
temp.splice(0, 1, duplicate);
console.log('18 temp is de laatste in de array');
}
i++
}
console.log('19 temp after replacing is: '+temp);

var play = global.get('play');
count = 0;
while(count <= 2){
var index = temp.indexOf('play' +(count + 1)); 

if (index !== -1) {
  temp[index] = play[count];
}
count++
}

temp.push('run sonos script again');
global.set('radio', temp);
console.log('20 temp is: '+temp);
}
var radioToday = temp[0];
//Logic variable radioToday
global.set('radioToday', radioToday);
//Logic variable radioUpdate
global.set('radioUpdate', true);
}

var radioToday = global.get('radioToday');
if (radioToday.substring(0, radioPrefix.length) === radioPrefix){
var title = radioToday.split('/').pop();
console.log('21 title is :'   +title);

}

count = 0
if (radioToday.substring(0, playListPrefix.length) === playListPrefix)
{
while(count <= playListId.length -1) 
{
if (radioToday.substring(radioToday.length - 22) === playListId[count].substring(0,22))
var title = playListName[count];
console.log('22 title is: '+title );
count++
}
global.set('title', title);
}

radio = global.get('radio');
console.log('23 radio is: ' +radio)
title = global.get('title')
console.log('24 '+title);
radioUpdate = global.get('radioUpdate')
console.log('25 radioUpdate is: '+radioUpdate)
}

Radio


Sonos api randomly playing radiostations and playlists

Apps used:

Other things people need to do to get it working correct?

Install the Sonos API


TEF:

[TEF:FLOWS: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]

Above you can import the flows with the app Device Capabilities