This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Check if SONOS queue is empty
#1
Hello, I'm trying to figure out a way to check if the queue on my SONOS is empty or not.
I programmed pushbuttons to control play/pauze and volume up/down. Works fine except when the queue is empty. In that case pushing the programmed play button is of course not starting anything, so it would be a nice feature if I could then just start my Default streaming radio station.
I thought of using the Transportstate ("STOPPED" would mean the queue is empty) but I noticed that the state also shortly goes to "STOPPED" in-between songs which makes it not 100% reliable.

Any suggestions would be kindly appreciated.
Reply
#2
Hi David,

You can get the number of items from the Sonos by using MediaRenderer  -> Queue -> Browse and then invoke with QueueID = 0, StartingIndex = 0, RequestedCount = 0

If you include this in your function upnpavcmd you should be able to get the NumberReturned value that holds the number of items inside the Queue

If NumberReturned = 0 then you can start your Radio URI

See attachment for screenshot from Device Spy with the fields you need

Good luck!

BR,

Erwin

Attached Files Thumbnail(s)
   
Reply
#3
Hi David,

I had some spare time and added it to the function:

Code:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
-- Set Sonos IP address sonos_ipaddress = '192.168.10.31' -- Function to send commands to Sonos function upnpavcmd(host, port, cmd, param)  local client, soap, reqs, service, res, err  require('socket')  client = socket.tcp()  client:settimeout(3)  -- Try connecting to upnp endpoint  res, err = client:connect(host, port)  if not res then    return nil, err  end  -- Guess service name based on command  if cmd == 'SetVolume' or  cmd == 'GetVolume' or  cmd == 'SetMute' or  cmd == 'GetMute' or  cmd == 'SetBass' or  cmd == 'GetBass' or  cmd == 'SetTreble' or  cmd == 'GetTreble' or  cmd == 'SetLoudness' or  cmd == 'GetLoudness' then    media = 'MediaRenderer'    service = 'RenderingControl'  elseif cmd == 'Browse' then    media = 'MediaServer'    service = 'ContentDirectory'  else    media = 'MediaRenderer'    service = 'AVTransport'  end  -- Soap envelope  soap = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' ..           '<s:Body>' ..             '<u:' .. cmd .. ' xmlns:u="urn:schemas-upnp-org:service:' .. service .. ':1">' ..               '<InstanceID>0</InstanceID>' ..               (param or '') ..             '</u:' .. cmd .. '>' ..           '</s:Body>' ..         '</s:Envelope>'  -- Http request    reqs = 'POST /' .. media .. '/' .. service .. '/Control HTTP/1.1\r\n' ..         'CONNECTION: close\r\n' ..         'HOST: ' .. host .. ':' .. port .. '\r\n' ..         'CONTENT-LENGTH: ' .. soap:len() .. '\r\n' ..         'CONTENT-TYPE: text/xml; charset="utf-8"\r\n' ..         'SOAPACTION: "urn:schemas-upnp-org:service:' .. service .. ':1#' .. cmd .. '"\r\n' ..         '\r\n' .. soap  -- Send http request  res, err = client:send(reqs)  if not res then    return nil, err  end  -- Get reply and close connection  res, err = client:receive('*a')  client:close()  return res, err end -- Get what's in the queue function getQueueContent(ip, port) BrowseConfig = '<ObjectID>Q:0</ObjectID>' ..  '<BrowseFlag>BrowseDirectChildren</BrowseFlag>' ..  '<Filter>*</Filter>' ..  '<StartingIndex>0</StartingIndex>' ..  '<RequestedCount>0</RequestedCount>' ..  '<SortCriteria>*</SortCriteria>'  result,err = upnpavcmd(ip, port, 'Browse', BrowseConfig)  return result,err end -- Command to get queue content and count (<NumberReturned>) queuecontent = getQueueContent(sonos_ipaddress, 1400) for i in string.gmatch(queuecontent, '<NumberReturned.-</NumberReturned>') do  if i ~= nil then    queuecount =  i:match([[<NumberReturned>(.-)</NumberReturned>]])    if queuecount then      queuecount = tonumber(queuecount)    end  end end -- Do action(s) based on number of items inside queue if queuecount > 0 then  -- Put here your normal play action else  -- Put here your URI play action end

BR,

Erwin van der Zwart
Reply
#4
Hello Erwin, first of all many thanks for looking into my question.
I tried the code you provided but something seems to be going wrong. I may be doing something wrong but I cannot seem to figure out exactly what.
Attached a screenshot of the error log + your code in the background. Apparently is goes wrong at line 74.

Any ideas what the cause of this might be?

Many thanks,
David

Attached Files Thumbnail(s)
   
Reply
#5
Hi David,

I checked, and there was indeed a small issue, but not on line 74. Did you copied the code from chrome? If yes please copy from other browser to avoid Chrome copy issue

Can you try to replace the code @ line 80:

Code:
1
queuecount =  i:match([[<NumberReturned>(.-)</NumberReturned>]])

with:

Code:
1
queuecount = string.match(i, '%d+')

BR,

Erwin

Attached Files Thumbnail(s)
   
Reply
#6
Hello Erwin, I copied with Safari. I had experienced problems before but I had no idea that this was related to the browser. I just retyped the lines until there were no reported faults anymore.
Tried it with Firefox now and that seems to work perfect.

Thanks for the tip :-)

With the brand new copy in Firefox and replacing the one line you suggested it works just fine now.

Thanks a lot for your help.

Best regards,
David
Reply


Forum Jump: