Aller au contenu

Sonos Play Stream (Musiques, Etc...)


Rem's

Messages recommandés

Cher Krikoff,

 

J'ai lu dans un de tes posts que l'on pouvait déclencher le titre en cours ou peut être faire appel à  d'autres .... Déclencher un sons, une sonnerie.

 

Tu parles d'utiliser la fonction "setAVtransportURI"

 

Pourrais tu m'en dire plus, voir me filer le code en question.

D'avance merci pour ton aide, je suis sur que d'autres "fibariste" seront également intéressés.

 

 

Modifié par Krikroff
Modification du titre
  • Upvote 1
Lien vers le commentaire
Partager sur d’autres sites

Sur la base de mon code pour le TTS, une nouvelle fonction "playFile"

-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
-- SONOS Play stream...
-- Copyright (C) 2014 Jean-Christophe Vermandé
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------

selfId = fibaro:getSelfId();    
ip = fibaro:get(selfId, 'IPAddress');
port = fibaro:get(selfId, 'TCPPort') or 1400;
currentTransportState = "";
lastTransportState = "";
currentVolume = 0;
lastVolume = 0;
ttsVolumeIsDifferent = false;

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 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" .. 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) 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

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(file, volume)
return sendSoapMessage(
-- control url
"/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-file-cifs:" .. file .. "</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

play();

end);
end

-- en paramètres: le fichier, puis le volume...
playFile("//HOME-SERVER/Musique/CD/Dream Theater/A Change of Seasons/01-A Change of Seasons [Medley].flac", 20); 

Voilou ;)

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

Salut Krikoff,

 

J'utilise ta fonction PlayFile pour lire des annonces vocales synthétisées qui sont enregistrées sur mon nas (alarme activée, arrosage en cours, sortir les poubelles, etc.). C'est vraiment très pratique :D

Je préfère cette fonction au TTS qui est finalement pas très agréable au quotidien (temps de latence, la voix pas terrible, problème des accents, fin de phrase tronquée)

Par contre, penses-tu qu'il est possible d'adapter le code pour reprendre la lecture en cours (radio, playlist...) ?

 

Merci ! @+

Lien vers le commentaire
Partager sur d’autres sites

  • 4 semaines après...

Bonjour Krilkroff,

 

Merci encore pour ton plugin SONOS, ça marche nickel. Je me régale avec ton TTS. Grâce à  toi je revis l'ambiance quai de gare et ses annonces si ....... belles ! (lol)

Dans un autre module, j'ai mis le script du dessus, mon soucis est ce message qui apparait dans Sonos : "Impossible de lire ... mon fichier... car serveur introuvable.

 

//Home_synology/volume1/music/03_LAST_NIGHT_(DIDDY_feat_KEYSHIA_COLE).mp3 (avec un autre fichier en ".flac" c'est pareil)

 

Aurais tu une idée, d'avance merci

Lien vers le commentaire
Partager sur d’autres sites

  • 6 mois après...

Bonjour a tous,

 

tout d'abord je voudrai te remerrci Krilkroff (ou JC, je ne sais pas trop bien encore) pour tout ce que tu m'as apporté afin de pouvoir commencer à  installer mon nouveau matos.

 

j'ai un Fibaro HC2 et une bar sons SONOS. j'ai reussis sans soucis à  utiliser ta solution de TTS mais je n'arrive pas à  utiliser ta fonction pour lire des PM3...

 

est ce que je dois ajouter cette fonction dans un device virtuel existant (le SONOS player)? ou dans un nouveau device virtuel? ou dans une scene? ou quelque part d'autre???

 

merci beaucoup pour ton aide et l'aide de toute la communauté.

 

Steven

Lien vers le commentaire
Partager sur d’autres sites

Merci beaucoup pour ta réponse.

 

je vais essayer avec un bouton mais je ne pense pas que je puisse simuler le click d'un bouton avec une scene... sinon je vais essayser de modifier le code pour le mettre dans une scene (j'ai la version 4.030 qui est stable de ce que j'ai compris :2: ...)

Lien vers le commentaire
Partager sur d’autres sites

Ben si tu vois

En revanche Dieu non ce n'est pas mon truc. Par contre toi tu peux m'appeler chaton des bois si tu veux mon biquet

Évidemment je plaisante, même pas en rêve pour chaton des bois

Envoyé de mon smartphone

  • Upvote 2
Lien vers le commentaire
Partager sur d’autres sites

Cher Krikroff CdB (Chaton des Bois),

 

tout fonctionne ou presque... le bouton fonctionne et je peux jouer des sons de mon NAS (conseil pour ceux qui veulent faire la même chose, le MP3 dans le NAS doit faire partie de la librairie du SONOS pour que ca fonctionne...).

 

j'ai ensuite créé une nouvelle scene et mis ce code:

fibaro:call(VD_ID, "pressButton", Button481);

ca me fait cette erreur:

 Runtime error: /opt/fibaro/FibaroSceneAPI.lua:252: attempt to concatenate local 'deviceID' (a nil value)

 

je suis malin et j'ai donc changé et testé avec ce code:

fibaro:call(VD_ID, "pressButton", "Button481");

mais ca me refait de nouveau cette erreur..

 Runtime error: /opt/fibaro/FibaroSceneAPI.lua:252: attempt to concatenate local 'deviceID' (a nil value)

 

maintenant je ne suis plus malin du tout et je viens pleurer vers toi....

qu'ai je fait faut encore...

 

aussi il y a t il quelque part une doc sur LUA et le fonction methode ect qui existe?

 

merci encore 1000 fois pour ton aide.

 

Steven

  • Upvote 1
Lien vers le commentaire
Partager sur d’autres sites

VD_ID c'est l'ID de ton vd module virtuel et pour le bouton il faut passer le numéro de l'élément correspondant... En fait tu comptes juste les éléments jusqu'au bouton.

Envoyé de mon smartphone

Lien vers le commentaire
Partager sur d’autres sites

merci pour cet info en effet ca fait du sens!

 

je continue avec mes questions (betes).... au moins ca fera de la documentation pour les autres....

mais je trouve le device ID de mes senseurs Fibaro mais pas le device ID des device virtuel... comment faire????

 

merci merci merci

Lien vers le commentaire
Partager sur d’autres sites

en fait... je suis assez nul et ca ne marche toujours pas...

2gx0akk.png

 

et j'ai mis comme code dans la scene:

--[[
%% properties

%% globals
--]]

fibaro:call(16, "pressButton", 16);

ca devrait donc jouer... mais evidemment ca ne joue pas...

 

merci au Ninja et au super héro pour votre aide....

 

Steven

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...