Sonos Lautsprecher befehle sprechen

Hallo,

ich habe auf YouTube gesehen, das es möglich sein soll das man über die Sonos Lautsprecher die im hc2 eingebunden sind,
verschieden Befehle sprechen lassen kann. Zum Beispiel “Türe geöffnet” oder “Alarmanlage scharf”.

Kennt jemand sowas oder hat es sogar schon realisiert?

Grüße

Ja, schau mal hier:
https://doonic.wordpress.com/2015/08/14/sonos-und-fibaro-hc2/

Habs jetzt bei mir laufen! Danke Hoogle!

Das Modul ist der Wahnsinn! Was da alles möglich ist.

Das Modul insbesondere der TTS Button läuft bei mir nicht. Kann es sein, dass Google bereits wieder etwas am Service geändert hat oder bin ich zu doof das einzurichten.

Hier mein Beispiel:



– 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 © return string.format ("%%%02X", string.byte©) 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)
fibaro:debug(“tts start”);
“<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>”,
fibaro:debug(“tts end”);
– 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(“de”, fibaro:getGlobalValue(“SONOS_TTS”), nil, 80);

Funktionierende URL im Browser: http://translate.google.com/translate_tts?client=t&tl=de&q=Willkommen+zu+Hause

Die Sonos Software gibt mir jeweils einen Fehler aus (siehe Anhang).

Danke für Eure Hilfe.

Gruss

Error.jpg

Hi,
Entweder Google oder Sonos:
http://forum.fibaro.com/index.php?/topic/19687-tts-sonos/page-2

Da haben mehrere Probleme…

VG Hoggle

Gibt es dazu schon eine Lösung?

Hi,

ja, VoiceRSS oder als mp3 abspielen.

Viele Grüße Hoggle

zB:
https://www.siio.de/board/thema/sonos_remote_v1-0-1/

Hi,

oder auch: https://youtu.be/5x39rsyrFJg
Allerdings wird ein zusätzlicher Rechner benötigt. Dafür gibt es eine vollständige Sonos Integration inkl. Gruppieren, etc.