Горячая линия Embedded System Rus:8-800-775-06-34 (звонок по России бесплатный)

LM5_N
LM-Wall_N
DALI_N
Vita_N

Управление аппаратурой SONOS из LogicMachine

Пример: Управление 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/>')