Aller au contenu

Chien Électronique À Base De Sonos


Eliah

Messages recommandés

Bonjour,

 

Je souhaitai mettre en place un Chien électronique à  partir d'un déclencheur type détecteur de mouvement fibaro. Mon but était que lorsqu'il y a un mouvement, un mp3 d'un chien qui aboie, qui est stocké sur mon NAS, se joue sur une de mes enceintes Sonos actuellement enregistré dans mon HC2 (v4) en module virtuel. Après d'âpres recherchent j'ai trouvé comment faire.. Merci aux contributeur de ce post qui m'ont donné envie de chercher ^_^

 

En avant la musique :

 

1- Ajoutez un module virtuel que l'on nommera "Chien Virtuel"

2- Ajouter l'adresse IP du Sonos que vous souhaitez utiliser pour diffuser le son

3- Ajouter le port 1400

4- Dans "Avancé", créez un bouton sur une seul ligne (dans Etiquette) et cliquez sur "ajouter un réglage"

5- Descendez pour éditer votre bouton et passez en mode "Code LUA"

6- Collez le code suivant :

------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
-- SONOS Play stream...
-- Copyright © 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

playFile("//SERV_DOMESTIK/Music/Sons/chien_2.mp3", 30);

7- Modifié le chemin de votre MP3 sur la dernière ligne : 

 

playFile("//SERV_DOMESTIK/Music/Sons/chien_2.mp3", 30);

 

le chiffre "30" correspond au volume de lecture

 

J'ai utilisé le son suivant : http://www.orangefreesounds.com/dog-bark-sound-2/

 

8-Enregistrez avec la disquette à  droite

8.5- Mon icon : http://www.domotique-fibaro.fr/index.php/gallery/album/260-chien-virtuel/

9- Créez une scène avec les "étiquettes magiques"

10- Personnellement j'ai mis : 

 

Si <Détecteur> == <en alerte>

Alors

<Module virtuel Chien><Button11> (pour moi c'est button11 mais pour vous ca peut être autre chose).

 

11- et voila ! Quand je bouge ca aboie ! 

 

C'est plein de scène que l'on peut faire avec des Mp3 enregistré du coup. Il devient possible de faire des retours audio à  des scénarios avec des sons pré-enregistré un peu comme SARAH mais du coup on évite le TTS :)

 

Je sens que je vais m'amuser ! :P

 

Merci et à  Bientôt ^_^

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

regarde ce VD de Krikroff, lorsque l'alarme se déclanche, il y a un message qui se diffuse automatiquement en boucle, par GEA

http://www.domotique-fibaro.fr/index.php/topic/616-device-sonos-player-t%C3%A9l%C3%A9commande-pour-diffuseur-sonos/?hl=sonos

 

 

en cherchant ta réponse, j'ai également trouvé ceci. ça pourrait être sympa

http://www.domotique-fibaro.fr/index.php/topic/1083-enregistrer-et-diffuser-un-message-sur-squeezebox-karotz-sonos/?hl=sonos

Lien vers le commentaire
Partager sur d’autres sites

tu peux aussi le faire autrement,

 

moi dans mon cas, on utilise Sarah avec le plugin PARLE .

 

et dans la HC2, nous avons un VD avec un bouton et voici le code dedans

 

Donc dès qu'un déclenchement suive a un mouvement ou une intrusion via une porte dans une scène, je demande dans ma scène de lancer le bouton du VD avec l'annonce ci dessous!

GET /sarah/parle?phrase=Alerte+intru+dans+la+maison+appel+police+en+cours HTTP/1.10x0D0x0A0x0D0x0A

Effectivement il n'aboi pas,  c'est aussi clair lol

Lien vers le commentaire
Partager sur d’autres sites

@cyberquat,

J'utilise "as is" le module virtuel de Krikroff, et je fais du TTS avec donc un message vocal en cas d'intrusion.

Mais la demande d'Eliah est de jouer un mp3 qui serait stocké quelque part sur un NAS.

Sais-tu comment configurer / quoi modifier dans le module de Krikroff pour lui faire jouer un mp3 dédié. (J'avais proposé la "solution" mais sans jamais l'avoir mise en oeuvre, et maintenant je voudrais essayer, et je n'y arrive pas)

Lien vers le commentaire
Partager sur d’autres sites

pour exemple,

 

moi dans mon cas avec ce plugin, je l'utilise le matin pour mettre une ambiance sonore apaisante a un moment précis.

 

Je n'ai rien fait de particulier en faite, dans l'application SONOS de Windows, j'ai juste intégrer mon NAS avec les mp3 et j'ai donc choisis un MP3 précis, c'est après dans ma scène de réveil le matin qu'il va chercher la mp3, et j'imagine que l'on peut le faire démarrer avec une détection sur le PLAY (bouton) le même mp3, lol suis je assez précis ?

Lien vers le commentaire
Partager sur d’autres sites

je ne suis pas encore un expert en sonos, mais, je vois qu'on peut faire le choix de la musique précise en créant une liste de lecture sonos et la faire jouer par le bouton play du module.

Mais on ne sais pas via le module lui dire de jouer telle ou telle liste, il va continuer àjouer ce qi était en cours (une liste de lecture, ou radio, ou ...)

Comment laisser le choix e jouer ce qu'on veux avec son android, et de forcer de jouer qqch de particulier avec sa HC2 ?

Lien vers le commentaire
Partager sur d’autres sites

hello, je viens de testé la chose, voici mon débug ^^

[DEBUG] 21:20:23: unMute sent
[DEBUG] 21:20:23: play sent
[DEBUG] 21:20:23: STOPPED
[DEBUG] 21:20:28: STOPPED
[ERROR] 21:20:31: line 190: attempt to call global 'stop' (a nil value)
Lien vers le commentaire
Partager sur d’autres sites

PITP2 : j'ai aussi essayer son module mais je n'ai réussi que par ma technique ^^

 

cybersquat : essaye d'enlever les commentaires dans le script sur la fonction STOP.. mais si tu l'enlèves le son se coupe au bout de 30 secondes :( Sinon pas d'autres idées

 

q.philippe : surement mais je ne sais pas comment :P Après je ne vois pas trop l'intérêt de modifier le volume sur le VD.. perso le son se joue à  un volume donné et ca me va bien comme ca. Si je dois faire d'autres sons avec d'autres volumes je créerai d'autres VD ^_^

Lien vers le commentaire
Partager sur d’autres sites

merci, mais ce soir pas possible.

Je suis là  : http://www.waterloo2015-live.org/fr/events/1053233/the-french-attack

 

Mon programme pour ce WE :

  • tondre pelouse
  • préparer sushis pour l'anniversaire de ma fille
  • déclaration d'impot
  • installer mon HP
  • m'occuper de ma femme
  • ...
Lien vers le commentaire
Partager sur d’autres sites

Lol j'ai pensé a toi lorsque aux infos ils ont parlés de waterloo je connais un peu ce coin. Moi je suis entrain de jouer Napoléon sur le forum pour la section anglais que moicphil veut peut être ouvrir

Envoyé de mon SM-G900F

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...