Aller au contenu
Krikroff

Fibaro Hc2 Vd Sonos Remote: Télécommande Pour Diffuseur Sonos

Recommended Posts

Hello,

 

mon TTS ne fonctionne plus non plus depuis un moment. Je ne comprends pas la solution de @gruberb : le code ne correspond pas du tout au code qui est présent dans les boutons du VD de @krikroff...!!

D'ailleurs, tes VD n'ont qu'un seul bouton... 

Dans l'attente ... :-)

Modifié par ebtjjn

Partager ce message


Lien à poster
Partager sur d’autres sites
Allez [mention=3]Krikroff[/mention] t'as encore du boulot
https://integration.sonos.com/


Yep, mais reste à voir si ce n’est pas comme à l’accoutumée un effet d’annonce histoire de faire le buzz !


Envoyé de mon iPhone en utilisant Tapatalk
  • Confused 1

Partager ce message


Lien à poster
Partager sur d’autres sites

 

Bonjour

Suite à une coupure de courant ce dimanche, ligne élec à foutu le feu à une grange, j'ai mes VD sonos qui sont en erreur.... et le Wachdog a relancé toute la nuit les VD.

(https://www.ladepeche.fr/article/2018/09/09/2865421-incendie-dans-une-grange-une-ligne-electrique-coupee.html)

 

 

Watchdog : VD « Sonos play base » (721) a été redémarré : 08:38:17 ERROR : line 82: attempt to index field \\\\\\\'zpStatus\\\\\\\' (a nil value)
[DEBUG] 08:39:14: -------------------------------------------------------------------------
[DEBUG] 08:39:14: -- HC2 Toolkit Framework version 1.0.6
[DEBUG] 08:39:14: -- Current interpreter version is Lua 5.1
[DEBUG] 08:39:14: -- Total memory in use by Lua: 233.54 Kbytes
[DEBUG] 08:39:14: -------------------------------------------------------------------------
[DEBUG] 08:39:14: Toolkit.Debug loaded in memory...
[DEBUG] 08:39:14: Benchmark [Toolkit.Debug lib]: elapsed time: 0.001 cpu secs
[DEBUG] 08:39:14: Toolkit.Collections.Queue loaded in memory...
[DEBUG] 08:39:14: Benchmark [Toolkit.Collections.Queue lib]: elapsed time: 0.001 cpu secs
[DEBUG] 08:39:14: Toolkit.Net loaded in memory...
[DEBUG] 08:39:14: Benchmark [Toolkit.Net lib]: elapsed time: 0.001 cpu secs
[DEBUG] 08:39:14: Toolkit.Xml loaded in memory...
[DEBUG] 08:39:14: Benchmark [Toolkit.Xml lib]: elapsed time: 0.001 cpu secs
[DEBUG] 08:39:14: Toolkit.HttpUtility loaded in memory...
[DEBUG] 08:39:14: Benchmark [Toolkit.HttpUtility lib]: elapsed time: 0.001 cpu secs
[DEBUG] 08:39:14: -------------------------------------------------------------------------
[DEBUG] 08:39:14: -- SONOS Advanced Remote version 1.0.0
[DEBUG] 08:39:15: -------------------------------------------------------------------------
[DEBUG] 08:39:15: SONOS Advanced Remote V 1.0.0 loaded in memory...
[DEBUG] 08:39:15: Benchmark [SONOS Advanced Remote V 1.0.0 lib]: elapsed time: 0.007 cpu secs
[ERROR] 08:39:17: line 82: attempt to index field 'zpStatus' (a nil value)

 

Pourtant les sonos fonctionnent parfaitement, il est possible d'écouter de la musique, j'arrive à faire jouer un MP3 ou un TTS....

Cependant il y a bien une erreur..

 

L'un de vous aurait une idée?

Merci

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour,

 

Essaie de supprimer ta variable sons_x_object, puis refais un "save" du VD. Cela recrééra la variable.

Partager ce message


Lien à poster
Partager sur d’autres sites
à l’instant, pepite a dit :

Bonjour,

 

Essaie de supprimer ta variable sons_x_object, puis refais un "save" du VD. Cela recrééra la variable.

 

Exacte

Tout est rentré dans l'ordre

Par contre il a fallut que je repasse sur l'ensemble des VD pour les ré-enregistrer

super merci bcp

 

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Salut j’ai voulu passer mes Sonos en filaire au lieu du wifi j’ai renseigné la nouvelle adresse ip dans le VD mais ça fonctionne plus il faut faire autre chose pour que ça fonctionne dès que je repasse en wifi tout est ok une idée merci 

Partager ce message


Lien à poster
Partager sur d’autres sites

es-tu sûr que l'IP est différente ? Car de mémoire (aussi surprenant que cela puisse paraître) quand j'étais en filaire ou Wifi, c'était la même MAC adresse qui était proposées (probablement à cause du réseau Wifinet de sonos ?)

Partager ce message


Lien à poster
Partager sur d’autres sites

Autant pour moi j’ai mal vue je me suis trompé d’enceinte Sonos donc oui l’adresse ip ne change pas et ça fonctionne en filaire 

Partager ce message


Lien à poster
Partager sur d’autres sites
Le 10/03/2017 à 12:37, drboss a dit :

-- SONOS Play playlist, v.0.1  () DrBoss 
-------------------------------------------------------------------------------------------
---made on source of:-----------------------------------------------------------------------
-- SONOS Play stream...
-- Copyright © 2014 Jean-Christophe Vermandé
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
----------------------------------
-- User Settings
----------------------------------

ip = "192.168.1.232"
port = 1400
FileVol = 10
PlayUnlimited = "Yes" -- si <> Yes, arrêt après 30s environ
--duration =
----------------------------------
-- DO not change bellow this line
---------------------------------- 
selfId = fibaro:getSelfId();    
--ip = fibaro:get(selfId, 'IPAddress');
--port = fibaro:get(selfId, 'TCPPort') or 1400;
currentTransportState = "";
lastTransportState = "";
currentVolume = 0;
lastVolume = 0;
ttsVolumeIsDifferent = false;
list_name = "Sonos Playlist  n1" --not implemented
list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
uid = "RINCON_BXE937B01XXXX1400" -- find by http://SONOS_IP:1400/status/upnp
urlencode = function(str)
  if (str) then
    str = string.gsub (str, "\n", "\r\n");
    str = string.gsub (str, "([^%w ])", function (c) return string.format ("%%%02X", string.byte(c)) end);
    str = string.gsub (str, " ", "+");
  end
  return str;
end
 
createRequestBody = function(action, schema, data)
  return string.format("<u:%s xmlns:u=\"%s\">%s</u:%s>", action, schema, data, action);
end
 
reponseCallback = function(fnc, args)
  if (fnc == nil) then
    return nil;
  end
  return fnc(args);
end
 
createSocket = function()
    -- Check IP and PORT before
  if (ip == nil or port == nil) then
    fibaro:debug("You must configure IPAddress and TCPPort first");
    return;
  end
  local socket;
  local status, err = pcall(function() 
      socket = Net.FTcpSocket(ip, port);
      socket:setReadTimeout(1000);
    end);  
  if (status ~= nil and status ~= true) then
    fibaro:debug("socket status: " .. tostring(status or ''));
  end  
  if (err ~= nil) then
    fibaro:debug("socket err: " .. tostring(err or ''));
    return;
  end
  return socket;
end
 
disposeSocket = function(socket)
  if (socket ~= nil) then
    socket:disconnect();
    socket = nil;
    return true;
  end
  return false;
end
 
sendSoapMessage = function(url, service, action, args, callback, retry)
 
  local socket = createSocket();
  if (socket == nil) then
    return;
  end
  retry = retry or 0
  -- prepare data
  local url = "POST " .. url .. " HTTP/1.1";
  --local udn = "X-SONOS-TARGET-UDN: uuid:RINCON_BXE937B01XXXX1400" -- udn of my SONOS (not need)
  local soapaction = "SOAPACTION: \"" .. service .. "#" .. action.name .. "\"";
  local body = createRequestBody(action.name, action.service, tostring(args or ""));
  local envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>" .. body .. "</s:Body></s:Envelope>";
  local ctl = "Content-Length: " .. string.len(envelope); 
  --local payload = url .. "\r\n" .. ctl .. "\r\n" .. udn .. "\r\n" .. soapaction .. "\r\n" .. "\r\n" .. envelope; -- with UDN
  local payload = url .. "\r\n" .. ctl .. "\r\n" .. soapaction .. "\r\n" .. "\r\n" .. envelope;
  -- write data
  local bytes, errorcode = socket:write(payload);
  if (errorcode == 0) then
    local state, errorcode = socket:read();
    if (errorcode == 0) then
      if (string.len(state or "") > 0) then
        -- callback
        if (callback ~= nil) then
          reponseCallback(callback, state);
        end
        -- dispose ...
        disposeSocket(socket);
        return true;
      else
        fibaro:debug("Error: Invalid response. response length: " .. string.len(state or ""));
      end
    else      
      if (retry < 5) then
        fibaro:debug("retry #"..retry.." action: " .. action.name);
        return sendSoapMessage(url, service, action, args, callback, (retry + 1));
      else
        fibaro:debug("Error: Code returned "..tostring(errorcode or ""));
      end
    end
  elseif (errorcode == 2) then
    fibaro:debug("Error: You must check your IP and PORT settings.");
  else
    if (retry < 5) then
      fibaro:debug("retry #"..retry.." action: " .. action.name);
      return sendSoapMessage(url, service, action, args, callback, (retry + 1));
    else
      fibaro:debug("Error: Code returned "..tostring(errorcode or ""));
    end
  end  
  -- dispose ...
  disposeSocket(socket);
  -- default response
  return false;
end
 
stop = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Stop", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)
      fibaro:debug("stop sent");
    end);    
end
 
unMute = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:RenderingControl:1",
    -- action
    { name = "SetMute", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredMute>0</DesiredMute>",
      -- callback (options)
    function(response)
      fibaro:debug("unMute sent");
    end); 
end
 
play = function(duration)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Play", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)   
      if (duration ~= nil) then
        fibaro:debug("play sent for " .. duration .. " seconds");
        fibaro:sleep(duration);
        stop();
      else
        fibaro:debug("play sent");
        local n = 0;
        currentTransportState = "TRANSITIONING";
        while (currentTransportState == "TRANSITIONING") do
          if (n > 10) then break end;
          getTransportState();
          fibaro:debug(currentTransportState);
          fibaro:sleep(5000);
          n = n + 1;
        end        
        local i = 0;
        currentTransportState = "PLAYING";
        while (currentTransportState == "PLAYING") do
         if (i > 10 and PlayUnlimited ~= "Yes") then break end;
          getTransportState();
          fibaro:debug(currentTransportState);
          fibaro:sleep(2000);
          i = i + 1;
        end
        fibaro:sleep(1000);
        stop();
      end
      -- update volume with value before tts if different
      if (ttsVolumeIsDifferent == true) then
      	setVolume(lastVolume);
        ttsVolumeIsDifferent = false;
      end
    end);    
end
 
 sseek = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Seek", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<Unit>TRACK_NR</Unit>,<Target>1</Target>",
      -- callback (options)
    function(response)   
 fibaro:debug("Seek");
 end);
end
 
 
  que = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>file:///jffs/settings/savedqueues.rsq#".. list_nbr.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="SQ:1" parentID="SQ:" restricted="true"><dc:title>".. list_name .."</dc:title><upnp:class>object.container.playlistContainer</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">RINCON_AssociatedZPUDN</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>1</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("que");
 end);
end
 
setVolume = function(value)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:RenderingControl:1",
    -- action
    { name = "SetVolume", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>" .. tostring(value) .. "</DesiredVolume>",
    -- callback (options)
    function(response)      
      fibaro:debug("Volume set: " .. value);
    end);
end
 
getVolume = function()
  fibaro:log("Get volume, please wait...");
  return sendSoapMessage(
    -- control url
  	"/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "GetVolume", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)    
    "<InstanceID>0</InstanceID><Channel>Master</Channel>",
    -- callback (options)
    function(response)
      currentVolume = tonumber(response:match("<CurrentVolume>(.+)</CurrentVolume>") or 0);    
    end);
end
 
getTransportState = function()
  return sendSoapMessage(
    -- control url
  	"/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "GetTransportInfo", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
    -- callback (options)
    function(response)      
      currentTransportState = response:match("<CurrentTransportState>(.+)</CurrentTransportState>") or "";
    end);
end
 
playFile= function(volume)
return sendSoapMessage(

-- control url  SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
"/MediaRenderer/AVTransport/Control",
-- service type
"urn:schemas-upnp-org:service:AVTransport:1",
-- action
{ name = "SetAVTransportURI", service = "urn:schemas-upnp-org:service:AVTransport:1" },
-- soap body data (options)
"<InstanceID>0</InstanceID>,<CurrentURI>x-rincon-queue:"..uid.."#0</CurrentURI>,<CurrentURIMetaData></CurrentURIMetaData>",



-- zestawienie playlist
-- control url
--"/MediaServer/ContentDirectory/Control",
-- service type
--"urn:schemas-upnp-org:service:ContentDirectory:1",
-- action
--{ name = "Browse", service = "urn:schemas-upnp-org:service:ContentDirectory:1" },
-- soap body data (options)
--"<ObjectID>Q:0</ObjectID>,<BrowseFlag>BrowseDirectChildren</BrowseFlag>,<Filter>dc:title,res,dc:creator,upnp:artist,upnp:album,upnp:albumArtURI</Filter>,<StartingIndex>0</StartingIndex>,<RequestedCount>100</RequestedCount>,<SortCriteria></SortCriteria></u:Browse>",
-- callback (options)
function(response)
-- retrieve current transport state
getTransportState();
lastTransportState = currentTransportState;
-- unmute before
unMute();
-- retrieve volume
getVolume();
lastVolume = currentVolume;
-- set tts volume if <> with current
if (volume ~= nil and volume ~= currentVolume) then
setVolume(volume);
ttsVolumeIsDifferent = true;
end
sseek();
play();
 
end);
end
 
-- en paramètres: le fichier, puis le volume...
que();
playFile(FileVol);

 

 

Bonjour... je suis en train de Vous demander un aide.. j'essaye d'utilier le lua pour changer le playlist du Sonos.. mais ne fonctione pas. j'ai crée un VD et apres le button avec le lua comme indique.. dans le debug.. je vois que le vd envoye la commande mais le sonos ne reponde pas. Est que vous avez quelque sugestion? Merci beaucoup en avance.

Modifié par Alexpelli

Partager ce message


Lien à poster
Partager sur d’autres sites
-- SONOS Play playlist, v.0.1  
-------------------------------------------------------------------------------------------
---made on source of:-----------------------------------------------------------------------
-- SONOS Play stream...
-- Copyright © 2014 Jean-Christophe Vermandé
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
----------------------------------
-- User Settings
----------------------------------

ip = "192.168.1.232"
port = 1400
FileVol = 10
PlayUnlimited = "Yes" -- si <> Yes, arrêt après 30s environ

--duration =
----------------------------------
-- DO not change bellow this line
---------------------------------- 
--selfId = fibaro:getSelfId();    
--album = fibaro:get(selfId, 'IPAddress');
--port = fibaro:get(selfId, 'TCPPort') or 1400;
currentTransportState = "";
lastTransportState = "";
currentVolume = 0;
lastVolume = 0;
ttsVolumeIsDifferent = false;
list_name = "Sonos Playlist  n1" --not implemented
list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
uid = "RINCON_B8E937B01D4E01400" -- find by http://SONOS_IP:1400/status/upnp
--album = "1kFVHozcxeXY3MfKB3F0yw"
--album = "22j1vb0GvgRdJ1AdbHtKXT"

spotify = "6he9MFK1bEvcA4dOByFJT3"

urlencode = function(str)
  if (str) then
    str = string.gsub (str, "\n", "\r\n");
    str = string.gsub (str, "([^%w ])", function (c) return string.format ("%%%02X", string.byte(c)) end);
    str = string.gsub (str, " ", "+");
  end
  return str;
end
 
createRequestBody = function(action, schema, data)
  return string.format("<u:%s xmlns:u=\"%s\">%s</u:%s>", action, schema, data, action);
end
 
reponseCallback = function(fnc, args)
  if (fnc == nil) then
    return nil;
  end
  return fnc(args);
end
 
createSocket = function()
    -- Check IP and PORT before
  if (ip == nil or port == nil) then
    fibaro:debug("You must configure IPAddress and TCPPort first");
    return;
  end
  local socket;
  local status, err = pcall(function() 
      socket = net.FTcpSocket(ip, port);
      socket:setReadTimeout(1000);
    end);  
  if (status ~= nil and status ~= true) then
    fibaro:debug("socket status: " .. tostring(status or ''));
  end  
  if (err ~= nil) then
    fibaro:debug("socket err: " .. tostring(err or ''));
    return;
  end
  return socket;
end
 
disposeSocket = function(socket)
  if (socket ~= nil) then
    socket:disconnect();
    socket = nil;
    return true;
  end
  return false;
end
 
sendSoapMessage = function(url, service, action, args, callback, retry)
 
  local socket = createSocket();
  if (socket == nil) then
    return;
  end
  retry = retry or 0
  -- prepare data
  --local url = "POST " .. url .. " HTTP/1.1";
  local url = "POST " .. url .. " HTTP/1.1\r\nHOST: ".. ip ..":1400";
  fibaro:debug(url)
  --local udn = "X-SONOS-TARGET-UDN: uuid:RINCON_B8E937B01D4E01400" -- udn of my SONOS (not need)
  local soapaction = "SOAPACTION: \"" .. service .. "#" .. action.name .. "\"";
  local body = createRequestBody(action.name, action.service, tostring(args or ""));
  local envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>" .. body .. "</s:Body></s:Envelope>";
  local ctl = "Content-Length: " .. string.len(envelope); 
  --local payload = url .. "\r\n" .. ctl .. "\r\n" .. udn .. "\r\n" .. soapaction .. "\r\n" .. "\r\n" .. envelope; -- with UDN
  local payload = url .. "\r\n" .. ctl .. "\r\n" .. soapaction .. "\r\n" .. "\r\n" .. envelope;
  -- write data
  local bytes, errorcode = socket:write(payload);
  if (errorcode == 0) then
    local state, errorcode = socket:read();
    if (errorcode == 0) then
      if (string.len(state or "") > 0) then
        -- callback
        if (callback ~= nil) then
          reponseCallback(callback, state);
        end
        -- dispose ...
        disposeSocket(socket);
        return true;
      else
        fibaro:debug("Error: Invalid response. response length: " .. string.len(state or ""));
      end
    else      
      if (retry < 5) then
        fibaro:debug("retry #"..retry.." action: " .. action.name);
        return sendSoapMessage(url, service, action, args, callback, (retry + 1));
      else
        fibaro:debug("Error: Code returned "..tostring(errorcode or ""));
      end
    end
  elseif (errorcode == 2) then
    fibaro:debug("Error: You must check your IP and PORT settings.");
  else
    if (retry < 5) then
      fibaro:debug("retry #"..retry.." action: " .. action.name);
      return sendSoapMessage(url, service, action, args, callback, (retry + 1));
    else
      fibaro:debug("Error: Code returned "..tostring(errorcode or ""));
    end
  end  
  -- dispose ...
  disposeSocket(socket);
  -- default response
  return false;
end
 
stop = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Stop", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)
      fibaro:debug("stop sent");
    end);    
end
 
 pause = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Pause", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)
      fibaro:debug("stop sent");
    end);    
end
 
 pnext = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Next", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
      -- callback (options)
    function(response)
      fibaro:debug("next sent");
    end);    
end

 pprev = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Previous", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
      -- callback (options)
    function(response)
      fibaro:debug("previous sent");
    end);    
end
 
unMute = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:RenderingControl:1",
    -- action
    { name = "SetMute", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredMute>0</DesiredMute>",
      -- callback (options)
    function(response)
      fibaro:debug("unMute sent");
    end); 
end
 
play = function(duration)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Play", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)   
        fibaro:debug("play sent");
    end);    
end
 
 sseek = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Seek", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<Unit>TRACK_NR</Unit>,<Target>1</Target>",
      -- callback (options)
    function(response)   
 fibaro:debug("Seek");
 end);
end
 
 

 
  sdel = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/Queue/Control",
    -- service type
    "urn:schemas-sonos-com:service:Queue:1",
    -- action
    { name = "RemoveAllTracks", service = "urn:schemas-sonos-com:service:Queue:1" },
    -- soap body data (options)
    "<QueueID>0</QueueID>,<UpdateID>0</UpdateID>",
      -- callback (options)
    function(response)   
 fibaro:debug("Remove");
 end);
end
 
  sonos_list = function(list_nbr)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>file:///jffs/settings/savedqueues.rsq#".. list_nbr.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="SQ:1" parentID="SQ:" restricted="true"><dc:title>".. list_name .."</dc:title><upnp:class>object.container.playlistContainer</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">RINCON_AssociatedZPUDN</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>1</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("set sonos playlist");
 end);
end
 
   spotify_list = function(spotify) --playlist from Spotify
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>x-rincon-cpcontainer:10062a6cspotify%3auser%3apdurbajlo%3aplaylist%3a"..spotify.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="10062a6cspotify%3auser%3apdurbajlo%3aplaylist%3a"..spotify.."" parentID="10082664playlists" restricted="true"><dc:title>Fibaro from Spotify</dc:title><upnp:class>object.container.playlistContainer</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>2</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("set spotify playlist");
 end);
end
 

 
 
spotify_album = function(album) --album from Spotify
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>x-rincon-cpcontainer:1004206cspotify%3aalbum%3a"..album.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="1004206cspotify%3aalbum%3a"..album.."" parentID="100d2064your_albums" restricted="true"><dc:title>Remote</dc:title><upnp:class>object.container.album.musicAlbum</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>2</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("set spotify album");
 end);
end
 
setVolume = function(value)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:RenderingControl:1",
    -- action
    { name = "SetVolume", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>" .. tostring(value) .. "</DesiredVolume>",
    -- callback (options)
    function(response)      
      fibaro:debug("Volume set: " .. value);
    end);
end
 
getVolume = function()
  fibaro:log("Get volume, please wait...");
  return sendSoapMessage(
    -- control url
  	"/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "GetVolume", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)    
    "<InstanceID>0</InstanceID><Channel>Master</Channel>",
    -- callback (options)
    function(response)
      currentVolume = tonumber(response:match("<CurrentVolume>(.+)</CurrentVolume>") or 0);    
    end);
end
 
getTransportState = function()
  return sendSoapMessage(
    -- control url
  	"/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "GetTransportInfo", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
    -- callback (options)
    function(response)      
      currentTransportState = response:match("<CurrentTransportState>(.+)</CurrentTransportState>") or "";
    end);
end


pause_play = function()
getTransportState()
fibaro:debug('wstrzymanie'..currentTransportState)
if currentTransportState == "PLAYING" then
  pause()
end
if currentTransportState == "PAUSED_PLAYBACK" then
  play()
end
end


playFile= function(volume)
return sendSoapMessage(

-- control url  SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
"/MediaRenderer/AVTransport/Control",
-- service type
"urn:schemas-upnp-org:service:AVTransport:1",
-- action
{ name = "SetAVTransportURI", service = "urn:schemas-upnp-org:service:AVTransport:1" },
-- soap body data (options)
"<InstanceID>0</InstanceID>,<CurrentURI>x-rincon-queue:"..uid.."#0</CurrentURI>,<CurrentURIMetaData></CurrentURIMetaData>",
-- callback (options)
function(response)
-- retrieve current transport state
getTransportState();
lastTransportState = currentTransportState;
-- unmute before
unMute();
-- retrieve volume
getVolume();
lastVolume = currentVolume;
-- set tts volume if <> with current
if (volume ~= nil and volume ~= currentVolume) then
setVolume(volume);
ttsVolumeIsDifferent = true;
end
sseek();
play();
 
end);
end




-- function for call
--[[
sdel(); -- remove last query
sonos_list(1) --list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
spotify_list("6he9MFK1bEvcA4dOBxxxxxx") -- "6he9MFK1bEvcA4dOByFJT3" playlist from spotify
spotify_album('22j1vb0GvgRdJ1Axxxxxx')  --22j1vb0GvgRdJ1AdbHtKXT album from spotify
playFile(FileVol); -- play file with volume z głośnością
pnext(); next track
pprev(); previus track
pause_play() -- swap play / pause, pause / play
stop(); -- stop
play(); -- play
pause()
Mute()
unMute()
sseek() -- seek
getTransportState() --current status of sonos
--]]

sdel(); -- remove last query
sonos_list(1) --list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
spotify_list("6he9MFK1bEvcA4dOByFJT3") -- "6he9MFK1bEvcA4dOByFJT3" playlist from spotify
spotify_album('22j1vb0GvgRdJ1AdbHtKXT')  --22j1vb0GvgRdJ1AdbHtKXT album from spotify
playFile(FileVol); -- play file with volume z głośnością
pnext(); next track
pprev(); previus track
pause_play() -- swap play / pause, pause / play
stop(); -- stop
play(); -- play
pause()
Mute()
unMute()
sseek() -- seek
getTransportState() --current status of sonos

 

 

after last upgrade in all VD based on Jean-Christophe source is important to add port number 1400 in URL of sonos device (in my example is line 104)

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 12 heures, drboss a dit :

-- SONOS Play playlist, v.0.1  
-------------------------------------------------------------------------------------------
---made on source of:-----------------------------------------------------------------------
-- SONOS Play stream...
-- Copyright © 2014 Jean-Christophe Vermandé
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
----------------------------------
-- User Settings
----------------------------------

ip = "192.168.1.232"
port = 1400
FileVol = 10
PlayUnlimited = "Yes" -- si <> Yes, arrêt après 30s environ

--duration =
----------------------------------
-- DO not change bellow this line
---------------------------------- 
--selfId = fibaro:getSelfId();    
--album = fibaro:get(selfId, 'IPAddress');
--port = fibaro:get(selfId, 'TCPPort') or 1400;
currentTransportState = "";
lastTransportState = "";
currentVolume = 0;
lastVolume = 0;
ttsVolumeIsDifferent = false;
list_name = "Sonos Playlist  n1" --not implemented
list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
uid = "RINCON_B8E937B01D4E01400" -- find by http://SONOS_IP:1400/status/upnp
--album = "1kFVHozcxeXY3MfKB3F0yw"
--album = "22j1vb0GvgRdJ1AdbHtKXT"

spotify = "6he9MFK1bEvcA4dOByFJT3"

urlencode = function(str)
  if (str) then
    str = string.gsub (str, "\n", "\r\n");
    str = string.gsub (str, "([^%w ])", function (c) return string.format ("%%%02X", string.byte(c)) end);
    str = string.gsub (str, " ", "+");
  end
  return str;
end
 
createRequestBody = function(action, schema, data)
  return string.format("<u:%s xmlns:u=\"%s\">%s</u:%s>", action, schema, data, action);
end
 
reponseCallback = function(fnc, args)
  if (fnc == nil) then
    return nil;
  end
  return fnc(args);
end
 
createSocket = function()
    -- Check IP and PORT before
  if (ip == nil or port == nil) then
    fibaro:debug("You must configure IPAddress and TCPPort first");
    return;
  end
  local socket;
  local status, err = pcall(function() 
      socket = net.FTcpSocket(ip, port);
      socket:setReadTimeout(1000);
    end);  
  if (status ~= nil and status ~= true) then
    fibaro:debug("socket status: " .. tostring(status or ''));
  end  
  if (err ~= nil) then
    fibaro:debug("socket err: " .. tostring(err or ''));
    return;
  end
  return socket;
end
 
disposeSocket = function(socket)
  if (socket ~= nil) then
    socket:disconnect();
    socket = nil;
    return true;
  end
  return false;
end
 
sendSoapMessage = function(url, service, action, args, callback, retry)
 
  local socket = createSocket();
  if (socket == nil) then
    return;
  end
  retry = retry or 0
  -- prepare data
  --local url = "POST " .. url .. " HTTP/1.1";
  local url = "POST " .. url .. " HTTP/1.1\r\nHOST: ".. ip ..":1400";
  fibaro:debug(url)
  --local udn = "X-SONOS-TARGET-UDN: uuid:RINCON_B8E937B01D4E01400" -- udn of my SONOS (not need)
  local soapaction = "SOAPACTION: \"" .. service .. "#" .. action.name .. "\"";
  local body = createRequestBody(action.name, action.service, tostring(args or ""));
  local envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>" .. body .. "</s:Body></s:Envelope>";
  local ctl = "Content-Length: " .. string.len(envelope); 
  --local payload = url .. "\r\n" .. ctl .. "\r\n" .. udn .. "\r\n" .. soapaction .. "\r\n" .. "\r\n" .. envelope; -- with UDN
  local payload = url .. "\r\n" .. ctl .. "\r\n" .. soapaction .. "\r\n" .. "\r\n" .. envelope;
  -- write data
  local bytes, errorcode = socket:write(payload);
  if (errorcode == 0) then
    local state, errorcode = socket:read();
    if (errorcode == 0) then
      if (string.len(state or "") > 0) then
        -- callback
        if (callback ~= nil) then
          reponseCallback(callback, state);
        end
        -- dispose ...
        disposeSocket(socket);
        return true;
      else
        fibaro:debug("Error: Invalid response. response length: " .. string.len(state or ""));
      end
    else      
      if (retry < 5) then
        fibaro:debug("retry #"..retry.." action: " .. action.name);
        return sendSoapMessage(url, service, action, args, callback, (retry + 1));
      else
        fibaro:debug("Error: Code returned "..tostring(errorcode or ""));
      end
    end
  elseif (errorcode == 2) then
    fibaro:debug("Error: You must check your IP and PORT settings.");
  else
    if (retry < 5) then
      fibaro:debug("retry #"..retry.." action: " .. action.name);
      return sendSoapMessage(url, service, action, args, callback, (retry + 1));
    else
      fibaro:debug("Error: Code returned "..tostring(errorcode or ""));
    end
  end  
  -- dispose ...
  disposeSocket(socket);
  -- default response
  return false;
end
 
stop = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Stop", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)
      fibaro:debug("stop sent");
    end);    
end
 
 pause = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Pause", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)
      fibaro:debug("stop sent");
    end);    
end
 
 pnext = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Next", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
      -- callback (options)
    function(response)
      fibaro:debug("next sent");
    end);    
end

 pprev = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Previous", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
      -- callback (options)
    function(response)
      fibaro:debug("previous sent");
    end);    
end
 
unMute = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:RenderingControl:1",
    -- action
    { name = "SetMute", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredMute>0</DesiredMute>",
      -- callback (options)
    function(response)
      fibaro:debug("unMute sent");
    end); 
end
 
play = function(duration)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Play", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Speed>1</Speed>",
      -- callback (options)
    function(response)   
        fibaro:debug("play sent");
    end);    
end
 
 sseek = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "Seek", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<Unit>TRACK_NR</Unit>,<Target>1</Target>",
      -- callback (options)
    function(response)   
 fibaro:debug("Seek");
 end);
end
 
 

 
  sdel = function()
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/Queue/Control",
    -- service type
    "urn:schemas-sonos-com:service:Queue:1",
    -- action
    { name = "RemoveAllTracks", service = "urn:schemas-sonos-com:service:Queue:1" },
    -- soap body data (options)
    "<QueueID>0</QueueID>,<UpdateID>0</UpdateID>",
      -- callback (options)
    function(response)   
 fibaro:debug("Remove");
 end);
end
 
  sonos_list = function(list_nbr)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>file:///jffs/settings/savedqueues.rsq#".. list_nbr.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="SQ:1" parentID="SQ:" restricted="true"><dc:title>".. list_name .."</dc:title><upnp:class>object.container.playlistContainer</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">RINCON_AssociatedZPUDN</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>1</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("set sonos playlist");
 end);
end
 
   spotify_list = function(spotify) --playlist from Spotify
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>x-rincon-cpcontainer:10062a6cspotify%3auser%3apdurbajlo%3aplaylist%3a"..spotify.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="10062a6cspotify%3auser%3apdurbajlo%3aplaylist%3a"..spotify.."" parentID="10082664playlists" restricted="true"><dc:title>Fibaro from Spotify</dc:title><upnp:class>object.container.playlistContainer</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>2</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("set spotify playlist");
 end);
end
 

 
 
spotify_album = function(album) --album from Spotify
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "AddURIToQueue", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>,<EnqueuedURI>x-rincon-cpcontainer:1004206cspotify%3aalbum%3a"..album.."</EnqueuedURI>,<EnqueuedURIMetaData><DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="1004206cspotify%3aalbum%3a"..album.."" parentID="100d2064your_albums" restricted="true"><dc:title>Remote</dc:title><upnp:class>object.container.album.musicAlbum</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc></item></DIDL-Lite></EnqueuedURIMetaData>,<DesiredFirstTrackNumberEnqueued>2</DesiredFirstTrackNumberEnqueued>,<EnqueueAsNext>1</EnqueueAsNext>",
      -- callback (options)
    function(response)   
 fibaro:debug("set spotify album");
 end);
end
 
setVolume = function(value)
  return sendSoapMessage(
    -- control url
    "/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:RenderingControl:1",
    -- action
    { name = "SetVolume", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>" .. tostring(value) .. "</DesiredVolume>",
    -- callback (options)
    function(response)      
      fibaro:debug("Volume set: " .. value);
    end);
end
 
getVolume = function()
  fibaro:log("Get volume, please wait...");
  return sendSoapMessage(
    -- control url
  	"/MediaRenderer/RenderingControl/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "GetVolume", service = "urn:schemas-upnp-org:service:RenderingControl:1" },
    -- soap body data (options)    
    "<InstanceID>0</InstanceID><Channel>Master</Channel>",
    -- callback (options)
    function(response)
      currentVolume = tonumber(response:match("<CurrentVolume>(.+)</CurrentVolume>") or 0);    
    end);
end
 
getTransportState = function()
  return sendSoapMessage(
    -- control url
  	"/MediaRenderer/AVTransport/Control",
    -- service type
    "urn:schemas-upnp-org:service:AVTransport:1",
    -- action
    { name = "GetTransportInfo", service = "urn:schemas-upnp-org:service:AVTransport:1" },
    -- soap body data (options)
    "<InstanceID>0</InstanceID>",
    -- callback (options)
    function(response)      
      currentTransportState = response:match("<CurrentTransportState>(.+)</CurrentTransportState>") or "";
    end);
end


pause_play = function()
getTransportState()
fibaro:debug('wstrzymanie'..currentTransportState)
if currentTransportState == "PLAYING" then
  pause()
end
if currentTransportState == "PAUSED_PLAYBACK" then
  play()
end
end


playFile= function(volume)
return sendSoapMessage(

-- control url  SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
"/MediaRenderer/AVTransport/Control",
-- service type
"urn:schemas-upnp-org:service:AVTransport:1",
-- action
{ name = "SetAVTransportURI", service = "urn:schemas-upnp-org:service:AVTransport:1" },
-- soap body data (options)
"<InstanceID>0</InstanceID>,<CurrentURI>x-rincon-queue:"..uid.."#0</CurrentURI>,<CurrentURIMetaData></CurrentURIMetaData>",
-- callback (options)
function(response)
-- retrieve current transport state
getTransportState();
lastTransportState = currentTransportState;
-- unmute before
unMute();
-- retrieve volume
getVolume();
lastVolume = currentVolume;
-- set tts volume if <> with current
if (volume ~= nil and volume ~= currentVolume) then
setVolume(volume);
ttsVolumeIsDifferent = true;
end
sseek();
play();
 
end);
end




-- function for call
--[[
sdel(); -- remove last query
sonos_list(1) --list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
spotify_list("6he9MFK1bEvcA4dOBxxxxxx") -- "6he9MFK1bEvcA4dOByFJT3" playlist from spotify
spotify_album('22j1vb0GvgRdJ1Axxxxxx')  --22j1vb0GvgRdJ1AdbHtKXT album from spotify
playFile(FileVol); -- play file with volume z głośnością
pnext(); next track
pprev(); previus track
pause_play() -- swap play / pause, pause / play
stop(); -- stop
play(); -- play
pause()
Mute()
unMute()
sseek() -- seek
getTransportState() --current status of sonos
--]]

sdel(); -- remove last query
sonos_list(1) --list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
spotify_list("6he9MFK1bEvcA4dOByFJT3") -- "6he9MFK1bEvcA4dOByFJT3" playlist from spotify
spotify_album('22j1vb0GvgRdJ1AdbHtKXT')  --22j1vb0GvgRdJ1AdbHtKXT album from spotify
playFile(FileVol); -- play file with volume z głośnością
pnext(); next track
pprev(); previus track
pause_play() -- swap play / pause, pause / play
stop(); -- stop
play(); -- play
pause()
Mute()
unMute()
sseek() -- seek
getTransportState() --current status of sonos

 

 

after last upgrade in all VD based on Jean-Christophe source is important to add port number 1400 in URL of sonos device (in my example is line 104)

Thank you.. I have tried your version but it doesn't work.. i got following error 

 

[ERROR] 08:49:19: line 285: ')' expected (to close '(' at line 277) near 'http'

Modifié par Alexpelli

Partager ce message


Lien à poster
Partager sur d’autres sites

Si @Alexpelli , le problème était lors de la copie du code source dans le forum. Les caractères >, <, etc ont été remplacés par  &gt, &lt. Il y a des fragments HTML dans le code LUA, ce qui explique pourquoi c'était un problème.

J'ajoute un exemple de VD qui fonctionne

sonos_example.vfib

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 48 minutes, drboss a dit :

Si @Alexpelli , le problème était lors de la copie du code source dans le forum. Les caractères >, <, etc ont été remplacés par  &gt, &lt. Il y a des fragments HTML dans le code LUA, ce qui explique pourquoi c'était un problème.

J'ajoute un exemple de VD qui fonctionne

sonos_example.vfib

Merci beaucoup drboss... j'ai importé le vd... mais encore j'ai des problems. La fonctionne del query, play et pause et stop ça marche. Album et List 1 malheuresement non. J'ai changé le ip de mon Sonos et le RINCON.. est que je dois indiquer le numero de albu, (--album = "22j1vb0GvgRdJ1AdbHtKXT")? Ou je peux trouver les numero des albums dans le Sonos? Ou le je changer le numero de playlist? Merci

Partager ce message


Lien à poster
Partager sur d’autres sites

Le numéro de l'album se trouve dans le client Spotify (PC).
Sur client Spotify tu sélectionné l'album intéressant, appuyez sur le bouton droit de la souris, puis "partager" et "copier le lien". Le numéro de l'album est le code après "album/" et devant les signes "? Si =" , emblable avec playlist.

https://open.spotify.com/album/22j1vb0GvgRdJ1AdbHtKXT?si=cOqvhLqtT4S53GdPIVq0pg

 

Pour list -  "sonos playlists" ( mémorisés dans le Sonos)  tu deve découvrir les numéros des listes en vérifiant à partir de 1. (sonos_list(1), sonos_list(2) ...)
Malheureusement, sonos a désactivé interface www des produits sonos.

Modifié par drboss

Partager ce message


Lien à poster
Partager sur d’autres sites

J'utilise principalement des listes créées dans Spotify ( spotify_list() ). Ceci est plus universel pour moi. Les lists Sonos que j'utilise pour la musique enregistrée sur le NAS domestique (mais de moins en moins) ;-)

 

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 27 minutes, drboss a dit :

Malheureusement, sonos a désactivé interface www des produits sonos.

Je ne suis pas certain de comprendre.... il n'y a plus de serveur Web intégré à chaque Sonos, donc plus d'API locale ?

Partager ce message


Lien à poster
Partager sur d’autres sites

 Hier je pensais que ça venait de ma connexion internet mais ce matin, pas de météo non plus donc je pense que ça a un rapport avec de la version 9 de Sonos qui vient de sortir.

Le module virtuel pour lire des mp3 (sur les Sonos) ne fonctionne plus non plus.

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

 Moi qui voulait me prendre une Sonos One pour la dédier aux messages de la box plus l'ajout de Google Home mais si plus rien ne marche avec la HC2, je reste avec ma Play 1.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Yes @Lazer  the api still exist, but without easy fast way to check many parameters by web interface (without xml and authorisation like in VD or via node)

When I wrote "Web" I things about http://x.x.x.x:1400/status/tracks etc.

 

  • Sad 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Thank's for the clarification.

 

Sonos makes things more complicated than they should be.... at least, I'm glad I quit Sonos for Yamaha Musiccast.

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 15 heures, Did a dit :

 Moi qui voulait me prendre une Sonos One pour la dédier aux messages de la box plus l'ajout de Google Home mais si plus rien ne marche avec la HC2, je reste avec ma Play 1.

 

il y a moyen de faire du TTS dans google Home, qui est encore plus rapide qu'avec Sonos.

Je suis entrain de regarder à cela (j'y suis arrivé, mais j'ai cassé mon SynoTest, donc il faut que je le reconstruise et recommence ...)

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 19 heures, drboss a dit :

Si @Alexpelli , le problème était lors de la copie du code source dans le forum. Les caractères >, <, etc ont été remplacés par  &gt, &lt. Il y a des fragments HTML dans le code LUA, ce qui explique pourquoi c'était un problème.

J'ajoute un exemple de VD qui fonctionne

sonos_example.vfib

Merci bcp pour le code. Je vais l'essayer ce soir.

En regardant les fonctions, je ne vois pas comment envoyer un mp3 qui se situe sur un diskstation. Avec le code de Krikroff je passais un stream avec cet url: 

//192.168.1.129/tts/2018_01.mp3

Partager ce message


Lien à poster
Partager sur d’autres sites

@drboss

Thanks a lot. It's work for me with spotify_list("xxxxxxx")

 

@Alexpelli

Dans le code, sous

-- function for call
--[[
sdel(); -- remove last query
sonos_list(1) --list_nbr = 1 -- playlist number on jffs system of SONOS, You need test it for find interesting list
spotify_list("6he9MFK1bEvcA4dOBxxxxxx") -- "6he9MFK1bEvcA4dOByFJT3" playlist from spotify
spotify_album('22j1vb0GvgRdJ1Axxxxxx')  --22j1vb0GvgRdJ1AdbHtKXT album from spotify
playFile(FileVol); -- play file with volume z głośnością
pnext(); next track
pprev(); previus track
pause_play() -- swap play / pause, pause / play
stop(); -- stop
play(); -- play
pause()
Mute()
unMute()
sseek() -- seek
getTransportState() --current status of sonos
--]]

Tu mets : (exemple fonctionnel avec une playlist spotify)
 

sdel() -- efface la playlist présente dans la liste de lecture s'il y en a une

spotify_list("7s1c8KpSSHIUlFz7iprMXj") -- la playlist concernée en passant par le client spotify comme l'explique @drboss
play() -- envoi la lecture ;-) 

 

@drboss

despite

PlayUnlimited = "Yes"

for me the playlist stop after 30 sec ;-)

Partager ce message


Lien à poster
Partager sur d’autres sites

×