Пример: Управление SONOS HiFi system из LogicMachine
Функции управления устройствами Sonos
Добавьте следующие функции в раздел Общие функции (Common functions).
function upnpavcmd(host, port, cmd, param)
local client, soap, reqs, service, res, err
require('socket')
client = socket.tcp()
client:settimeout(3)
-- try connecting to upnp endpoint
res, err = client:connect(host, port)
if not res then
return nil, err
end
-- guess service name based on command
if cmd == 'SetVolume' or cmd == 'GetVolume' or cmd == 'SetMute' or cmd == 'GetMute'
then
service = 'RenderingControl'
else
service = 'AVTransport'
end
-- soap envelope
soap = '' ..
'' ..
'<u:' .. cmd .. ' xmlns:u="urn:schemas-upnp-org:service:' .. service .. ':1">' ..
'0' ..
(param or '') ..
'' ..
'' ..
''
-- http request
reqs = 'POST /MediaRenderer/' .. service .. '/Control HTTP/1.1\r\n' ..
'CONNECTION: close\r\n' ..
'HOST: ' .. host .. ':' .. port .. '\r\n' ..
'CONTENT-LENGTH: ' .. soap:len() .. '\r\n' ..
'CONTENT-TYPE: text/xml; charset="utf-8"\r\n' ..
'SOAPACTION: "urn:schemas-upnp-org:service:' .. service .. ':1#' .. cmd .. '"\r\n' ..
'\r\n' .. soap
-- send http request
res, err = client:send(reqs)
if not res then
return nil, err
end
-- get reply and close connection
res, err = client:receive('*a')
client:close()
return res, err
end
Событийный скрипт, который отправляет значение громкости и другие команды на устройство SONOS:
-- ip, port, command, optional param
upnpavcmd('192.168.1.52', 1400, 'SetVolume', 'Master20')
upnpavcmd('192.168.1.52', 1400, 'Pause')
upnpavcmd('192.168.1.52', 1400, 'Play', '1')
upnpavcmd('192.168.1.52', 1400, 'Next')
upnpavcmd('192.168.1.52', 1400, 'Previous')
upnpavcmd('192.168.1.52', 1400, 'SetMute', 'Master0')
upnpavcmd('192.168.1.52', 1400, 'SetMute', 'Master1')
Скрипт по расписанию для поиска устройств воспроизведения SONOS:
—код из файла sonos_sched.lua
require("socket")
require('socket.http')
local udp = socket.udp()
udp:settimeout(5)
if udp == nil then
return
else
local result, message
local datagram = "M-SEARCH * HTTP/1.1\r\n"
.. "HOST: 239.255.255.250:1900\r\n"
.. "ST: urn:schemas-upnp-org:device:ZonePlayer:1\r\n"
.. "\r\n"
result, message = udp:sendto(datagram, "239.255.255.250", 1900)
for i = 1, 254 do
datagram, message = udp:receivefrom()
if datagram == nil then
break
else
ip = datagram:match("LOCATION: http://(.-):1400/xml/device_description.xml")
if ip then -- Fix for other UPNP devices like Philips Hue.
data = socket.http.request("http://" .. ip .. ":1400/status/zp")
zonename = data:match([[(.+).+%((%a+)%)]]) -- Fix for Sonos stereo pair
if zonename == nil then
zonename = data:match([[(.+)]])
end
pair = data:match([[.+%((%a+)%)]])
if pair == "R" then
log("Zoneplayer is part of a stereo pair and can't be used as a seperate zone " .. ip)
elseif pair == "L" then
log(zonename:gsub("%s", "-") .. " " .. ip)
storage.set(zonename:gsub("%s", "-"), ip)
-- Create storage with zonename and ip address.
--This can be used for the Sonos scripts (stereo pair)
elseif pair == nil then
log(zonename:gsub("%s", "-") .. " " .. ip)
storage.set(zonename:gsub("%s", "-"), ip)
-- Create storage with zonename and ip address.
--This can be used for the Sonos scripts (seperate player)
end
else
log("No Sonos device: " .. datagram)
break
end
end
end
end
udp:close()
Вопросы/ответы
В: Как регулировать уровень громкости звука?
О: Невозможно относительно регулировать громкость (то есть отправить команду «увеличить громкость» или «уменьшить громкость»). Поэтому необходимо получить текущее значение громкости, разобрать полученный ответ и отправить новое значение громкости звука.
res = upnpavcmd('192.168.1.52', 1400, 'GetVolume', '<Channel>Master</Channel>')
В: Как проигрывать плейлист Spotify или определенное радио?
О: Можно использовать следующий код (пример для радио):
upnpavcmd('192.168.1.52', 1400, 'SetAVTransportURI', '<CurrentURI>
x-rincon-mp3radio://www.abc-lounge.com/listen.m3u</CurrentURI><CurrentURIMetaData/>')