Aller au contenu

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


Krikroff

Messages recommandés

merci i-magin ;) mais ça ne marche pas pour moi qui utilise que la partie TTS, d'ailleurs si qqle un à  une idée je l'a prends avec plaisir ;)  :2:  :77:

Voici le code entier et on peut voir qu'a la ligne 260 j'ai remplacer par ce que tu as mis plus haut. 

 
------------------------------------------------------------------------------------------- 
------------------------------------------------------------------------------------------- 
-- SONOS Text To Speech (TTS) - Give voice to your HC2 with SONOS wireless speakers 
-- Version 0.0.4 pre-release 
-- Copyright © 2014 Jean-Christophe Vermandé 
------------------------------------------------------------------------------------------- 
------------------------------------------------------------------------------------------- 
 
selfId = fibaro:getSelfId();    
ip = fibaro:get(selfId, 'IPAddress'); 
port = fibaro:get(selfId, 'TCPPort'); 
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 
 
playTTS = function(lng, message, duration, 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-rincon-mp3radio://translate.google.com/translate_tts?tl=".. lng .. "&a" .. "mp;q=" .. urlencode(message) .. "</CurrentURI>,<CurrentURIMetaData></CurrentURIMetaData>",
    "<InstanceID>0</InstanceID>,<CurrentURI>x-rincon-mp3radio://translate.google.com/translate_tts?ie=UTF-8,client=t".."&a".."mp;tl=".. (lng or "fr") .. "&a" .. "mp;q=" .. (urlEncode(message or "") or "message") .. "</CurrentURI><CurrentURIMetaData>"..Sonos:createMetaData("TSS by Google...").."</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 tts 
      fibaro:debug("tts: " .. message); 
      if (duration ~= nil) then 
        play(duration); 
      else 
        play(); 
      end 
    end);  
end 
 
playTTS("fr", "Attention, les volets du sejour et de la cuisine vont se fermer", nil, 50); 
 
Lien vers le commentaire
Partager sur d’autres sites

J'ai partagé ma bidouille dès que j'ai constaté le bon fonctionnement, mais en précisant que c'était "dans l'attente du retour de @Krikroff"  ;)

 

Ensuite,  j'ai constaté que j'aurais peut-être dà» proposer ce code :

"<InstanceID>0</InstanceID><CurrentURI>x-rincon-mp3radio://translate.google.com/translate_tts?ie=UTF-8".."&a".."mp;client=".."t" .."&a".."mp;tl=".. (lng or "fr") .. "&a" .. "mp;q=" .. (urlEncode(message or "") or "message") .. "</CurrentURI><CurrentURIMetaData>"..Sonos:createMetaData("TSS by Google...").."</CurrentURIMetaData>",

Mais je vous propose d'attendre @Krikroff qui va nous donner la bonne solution...

 

@Rocketlud, je ne connaissais pas le code de @Krikroff que tu présentes ... une ancienne version TTS avant son module virtuel ?

Je suppose :

- qu'il fonctionnait avant la modification de Google qui exige un code "captcha" ?

- que tu as lancé le débogage ?

 

Tu peux essayer ceci :

"<InstanceID>0</InstanceID>,<CurrentURI>x-rincon-mp3radio://translate.google.com/translate_tts?client=".."t" .."&a".."mp;tl=".. lng .. "&a" .. "mp;q=" .. urlencode(message) .. "</CurrentURI>,<CurrentURIMetaData></CurrentURIMetaData>",
  • Upvote 2
Lien vers le commentaire
Partager sur d’autres sites

LOL, sorry Pascal, j'avais pas compris que la question était pour moi   :3:

 

Je l'ai trouver sur le fofo, mais je ne sais plus ou , trop de soleil dans le nord, on a pas l'habitude, ça chauffe trop le cerveau  :2:

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

  • 3 semaines après...

@jojo:

Bon après recherche, rebelote ce matin.

Effectivement, c'est j'ai des soucis avec le wifi de ma freebox qui "disparait" de temps àautre donc les Sonos étaient déconnectés.

Prochaine étape: créer un script qui vérifie que le réseau wifi est ok et sinon rédémarrer automatiquement la FB.

Lien vers le commentaire
Partager sur d’autres sites

J'utilise le PCL pour imprimer sur mon imprimante laser, mais j'ai jamais testé sur les Sonos :94:

 

Plus sérieusement, ce qui est génial avec les Sonos c'est qu'on a le choix Wifi ou Ethernet, et clairement le fil ça change la vie. Puisque j'en parle, même mon imprimante fonctionne beaucoup mieux depuis qu'elle est en filaire. Le Wifi c'est bien pour les appareils mobiles, mais peu adapté aux équipements fixes, et encore moins aux équipements qui doivent échanger une grosse quantité de données (PC qui télécharge, webcam, pc home-cinéma, sonos).

En plus avec les Sonos, une fois câblé en filaire, on peut désactiver la gestion du Wi-Fi, ils ont pensé à  tout !

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

@sakkhho, vu que rems ne veut pas te répondre  ;)  je te dis oui le tts fonctionne bien sur le playbar et la qualité du playbar est bonne vu son faible encombrement.

 

@benji, yes un support mural existe pour la playbar environ 50€

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...