Welcome to Smart Home Forum by FIBARO
Dear Guest,
as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.
As a member you can:
- Start new topics and reply to others
- Follow topics and users to get email updates
- Get your own profile page and make new friends
- Send personal messages
- ... and learn a lot about our system!
Regards,
Smart Home Forum by FIBARO Team

Question
Hallamnet 17
Hi all.
I have install this Sonos VD to play MP3's at a click of a button.
Short files work fine like sound effects but full music tracks only play for about 20 seconds.
Can anyone help with this.
I have attached the LUA below so you can see what I am using. All you have to do is change the last line to where your MP3 is and the required volume and that's it.
Look forward to the reply.
Regards,
Andy
------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
-- 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("//192.168.1.247/Music/Incoming.mp3", 70);
Please login or register to see this attachment.
2 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.