Integracja z Systemami Mulitroom SONOS

Celem niniejszego artykułu jest zaprezentowanie przykładu integracji systemu mulitroom Sonos z Systemem Grenton Smart Home z wykorzystaniem Gate Http



Urządzenie, które zostało zastosowane w tym przykładzie to SONOS ONE

Integracja ta pozwala nam na: 

  • sterowaniem nagłośnieniem
  • Play, Pause, Next, Previous
  • odczyt aktualnego utworu/albumu

Do zrealizowania poniższego przykładu potrzebujemy:

  • CLU Z-Wave
  • Gate HTTP
  • Inteligentny głośnik SONOS

Przygotowanie

  1. W pierwszym kroku należy skonfigurować głośnik Sonos i połączyć go z lokalną siecią, w której znajduje się CLU i Gate Http.
  2. Następnie należy przygotować dwa obiekty wirtualne HttpRequest. (GET i POST)

  • Obiekt HttpRequest o przykładowej nazwie "HttpRequest_post" uzupełniam jak poniżej:

Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/AVTransport/Control

Method: POST

RequestType: XML 

ResponseType: XML


  • Obiekt HttpRequest o przykładowej nazwie "HttpRequest_get_volume" uzupełniam jak poniżej:

Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/RenderingControl/Control

Method: GET

RequestType: XML 

ResponseType: XML






Sterowanie nagłośnieniem


Do płynnego sterowania nagłośnieniem będzie potrzebna informacja o obecnej wartości głośności. W tym celu należy przygotować skrypt, który zrealizuje zapytanie o tą wartość i przekaże ją do cechy użytkownika. Poniżej opis jak należy to wykonać:


  • W pierwszym kroku należy utworzyć cechę użytkownika w module Gate Http o przykładowej nazwie "SONOS_volume"

  • Następnie skrypt o nazwie "Sonos_volume_get", który wyśle zapytanie:
local body, header, user

        user = {xmlTag = 's:Body',{xmlTag = 'u:GetVolume',['xmlns:u'] = 'urn:schemas-upnp-org:service:RenderingControl:1',{xmlTag = 'InstanceID',0 },{xmlTag = 'Channel','Master'}}}
        header = {['SOAPAction'] = "urn:schemas-upnp-org:service:RenderingControl:1#GetVolume",}
        body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}
    


    Gate_HTTP->HttpRequest_get_volume->SetRequestHeaders(header)
    Gate_HTTP->HttpRequest_get_volume->SetRequestBody(body)
    Gate_HTTP->HttpRequest_get_volume->SendRequest()
    
  • Oraz kolejny skrypt "Sonos_resp_volume", który pobierze wartość z cechy ResponseBody i przekaże jej wartość do cechy użytkownika "SONOS_volume"  
local resp

  resp = Gate_HTTP->HttpRequest_get_volume->ResponseBody   
    Gate_HTTP->SONOS_volume = tonumber(resp[1][1][1][1])

 

Skrypt ten należy wywołać przez zdarzenie OnResponse obiekcie wirtualnym HttpRequest "HttpRequest_get_volume"


Po wysłaniu konfiguracji i uruchomieniu skryptu "Sonos_volume_get", cecha StatusCode przyjmie wartość 200



 a wartość cechy użytkownika "SONOS_volume" zostanie zaktualizowana:

    

Gdy już znamy wartość nagłośnienia, możemy wykonać sterowanie głośnością. W tym celu musimy przygotować skrypty, które zrealizują inkrementację, dekrementację lub wyzerują wartości Volume. Poniżej opis jak można to wykonać:



  • Tworzymy skrypty "sonos_volume_up" realizujący inkrementację
local header,body,user,vol,path
    
    Gate_HTTP->Sonos_volume_get()
    SYSTEM.Wait(100)
    vol = Gate_HTTP->SONOS_volume
    vol = vol + 1    

         
    header = {['SOAPAction'] = "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume",}
    user = {xmlTag = 's:Body',{xmlTag = 'u:SetVolume',['xmlns:u'] = 'urn:schemas-upnp-org:service:RenderingControl:1',{xmlTag = 'InstanceID',0 }, 
            {xmlTag = 'Channel','Master'},{xmlTag = 'DesiredVolume',vol}}}
    path = "/MediaRenderer/RenderingControl/Control"
    
    body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}

Gate_HTTP->HttpRequest_post->SetPath(path)
Gate_HTTP->HttpRequest_post->SetRequestHeaders(header)
Gate_HTTP->HttpRequest_post->SetRequestBody(body)
Gate_HTTP->HttpRequest_post->SendRequest()
Gate_HTTP->Sonos_volume_get()
  • Następnie skrypt "sonos_volume_down" realizujący dekrementację
local header,body,user,vol,path

    
    Gate_HTTP->Sonos_volume_get()
    SYSTEM.Wait(100)
    vol = Gate_HTTP->SONOS_volume
    vol = vol - 1    

         
    header = {['SOAPAction'] = "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume",}
    user = {xmlTag = 's:Body',{xmlTag = 'u:SetVolume',['xmlns:u'] = 'urn:schemas-upnp-org:service:RenderingControl:1',{xmlTag = 'InstanceID',0 }, 
            {xmlTag = 'Channel','Master'},{xmlTag = 'DesiredVolume',vol}}}
    path = "/MediaRenderer/RenderingControl/Control"
    
    body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}

Gate_HTTP->HttpRequest_post->SetPath(path)
Gate_HTTP->HttpRequest_post->SetRequestHeaders(header)
Gate_HTTP->HttpRequest_post->SetRequestBody(body)
Gate_HTTP->HttpRequest_post->SendRequest()
Gate_HTTP->Sonos_volume_get()
  • Oraz skrypt "sonos_volume_mute", który wyciszy głośnik
local header,body,user,path,vol 

    vol = 0    

         
    header = {['SOAPAction'] = "urn:schemas-upnp-org:service:RenderingControl:1#SetVolume",}
    user = {xmlTag = 's:Body',{xmlTag = 'u:SetVolume',['xmlns:u'] = 'urn:schemas-upnp-org:service:RenderingControl:1',{xmlTag = 'InstanceID',0 }, 
            {xmlTag = 'Channel','Master'},{xmlTag = 'DesiredVolume',vol}}}
    path = "/MediaRenderer/RenderingControl/Control"

    body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}

Gate_HTTP->HttpRequest_post->SetPath(path)
Gate_HTTP->HttpRequest_post->SetRequestHeaders(header)
Gate_HTTP->HttpRequest_post->SetRequestBody(body)
Gate_HTTP->HttpRequest_post->SendRequest()
Gate_HTTP->Sonos_volume_get()

Po wysłaniu konfiguracji, uruchomienie wyżej wymienionych skryptów spowoduje zmianę nagłośnienia.






Pobieranie informacji o utworze, wykonawcy, albumie


Do uzyskania informacji o obecnie odtwarzanym utworze, albumie lub wykonawcy należy wykonać poniższe kroki:


  • W pierwszym kroku należy stworzyć obiekt wirtualny o nazwie "HttpRequest_get_info"


Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/AVTransport/Control

Method: GET

RequestType: XML 

ResponseType: XML


  • W kolejnym kroku musimy utworzyć cechy użytkownika, do których zostaną przekazane informację:


Znaczenie cech użytkownika:

track - tytuł utworu

artist - wykonawca

duration - długość utworu

rel_time - czas trwania utworu

album - tytuł albumu


  • Następnie należy utworzyć skrypt "sonos_info_get
local user, body, header, path
    
    
    user = { xmlTag = 's:Body', {xmlTag = 'u:GetPositionInfo', ['xmlns:u'] = 'urn:schemas-upnp-org:service:AVTransport:1', { xmlTag = 'InstanceID',0 }}}
    header = {['SOAPAction'] = "urn:schemas-upnp-org:service:RenderingControl:1#GetPositionInfo",}
    path = "/MediaRenderer/AVTransport/Control"
    body = { xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}
    
    Gate_HTTP->HttpRequest_get_info->SetPath(path)
    Gate_HTTP->HttpRequest_get_info->SetRequestHeaders(header)
    Gate_HTTP->HttpRequest_get_info->SetRequestBody(body)
    Gate_HTTP->HttpRequest_get_info->SendRequest()

 

  • Oraz skrypt "sonos_info_resp", który zrealizuje odczyt wysłanej odpowiedzi
local resp, did1

resp = Gate_HTTP->HttpRequest_get_info->ResponseBody
didl = xml.parse(resp[1][1][3][1])

Gate_HTTP->track = didl[1][4][1] 
Gate_HTTP->artist = didl[1][6][1]
Gate_HTTP->album = didl[1][7][1]
Gate_HTTP->duration = resp[1][1][2][1]
Gate_HTTP->rel_time = resp[1][1][5][1]

 

Skrypt ten należy wywołać przez zdarzenie OnResponse obiekcie wirtualnym HttpRequest "HttpRequest_get_info"



Po wysłaniu konfiguracji i uruchomieniu skryptu "sonos_info_get" cecha StatusCode przyjmie wartość 200


 a wartości cech użytkownika zostaną zaktualizowane






Sterowanie odtwarzaniem (Play, Pause, Next, Previous)


Do kontrolowania odtwarzanej muzyki (Play, Pause) musimy znać stan głośnika. W tym celu należy wykonać poniższe kroki:


  • W pierwszym kroku należy utworzyć cechę użytkownika w module Gate Http o przykładowej nazwie "state"

  • oraz obiekt wirtualny HttpRequest o nazwie "HttpRequest_get_state"


Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/AVTransport/Control

Method: GET

RequestType: XML 

ResponseType: XML




  • następnie musimy utworzyć skrypt "sonos_state_get"
local body,head,path, user  


    user = {xmlTag = 's:Body',{xmlTag = 'u:GetTransportInfo',['xmlns:u'] = 'urn:schemas-upnp-org:service:AVTransport:1',{xmlTag = 'InstanceID',0}}}
    header = {['SOAPAction'] = "urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo",}
    path = "/MediaRenderer/AVTransport/Control"
    body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}
  

  Gate_HTTP->HttpRequest_get_state->SetPath(path)
  Gate_HTTP->HttpRequest_get_state->SetRequestHeaders(header)
  Gate_HTTP->HttpRequest_get_state->SetRequestBody(body)
  Gate_HTTP->HttpRequest_get_state->SendRequest()

 

  • oraz skrypt "sonos_state_get_resp", który przekaże informacje do cechy użytkownika
local resp

resp = Gate_HTTP->HttpRequest_get_state->ResponseBody
Gate_HTTP->state = resp[1][1][1][1]

 

  • Skrypt ten należy wywołać przez zdarzenie OnResponse w obiekcie wirtualnym HttpRequest "HttpRequest_get_state"

Po wysłaniu konfiguracji i uruchomieniu skryptu "sonos_state_get", cecha StatusCode przyjmie wartość 200


 a wartość cechy użytkownika zostanie zaktualizowana:




Gdy już znamy stan pracy głośnika, możemy wykonać skrypty sterujące funkcjami Play, Pause, Next, Previous



  • skrypt "sonos_play_pause":

local header,body,user,path
if (Gate_HTTP->state == "PAUSED_PLAYBACK" or Gate_HTTP->state == "STOPPED") then
  
  header = {['SOAPAction'] = "urn:schemas-upnp-org:service:AVTransport:1#Play",}
  user = {xmlTag = 's:Body',{xmlTag = 'u:Play' ,['xmlns:u'] = 'urn:schemas-upnp-org:service:AVTransport:1',{xmlTag = 'InstanceID',0 },{xmlTag = 'Speed',1 },}}  
  path = "/MediaRenderer/AVTransport/Control"
  body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}


else

  header = {['SOAPAction'] = "urn:schemas-upnp-org:service:AVTransport:1#Pause",}
  user = {xmlTag = 's:Body',{xmlTag = 'u:Pause' ,['xmlns:u'] = 'urn:schemas-upnp-org:service:AVTransport:1',{xmlTag = 'InstanceID',0 },{xmlTag = 'Speed',1 },}}  
  path = "/MediaRenderer/AVTransport/Control"
  body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}
end
Gate_HTTP->HttpRequest_post->SetPath(path)
Gate_HTTP->HttpRequest_post->SetRequestHeaders(header)
Gate_HTTP->HttpRequest_post->SetRequestBody(body)
Gate_HTTP->HttpRequest_post->SendRequest()
Gate_HTTP->sonos_state_get()
  • Skrypt "sonos_next"
local header,body,user,path




  header = {['SOAPAction'] = "urn:schemas-upnp-org:service:AVTransport:1#Next",}
  user = {xmlTag = 's:Body',{xmlTag = 'u:Next' ,['xmlns:u'] = 'urn:schemas-upnp-org:service:AVTransport:1',{xmlTag = 'InstanceID',0 },{xmlTag = 'Speed',1 },}}  
  path = "/MediaRenderer/AVTransport/Control"
  body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}

Gate_HTTP->HttpRequest_post->SetPath(path)
Gate_HTTP->HttpRequest_post->SetRequestHeaders(header)
Gate_HTTP->HttpRequest_post->SetRequestBody(body)
Gate_HTTP->HttpRequest_post->SendRequest()
Gate_HTTP->sonos_state_get()
  • Skrypt "sonos_previous
local header,body,user,path




  header = {['SOAPAction'] = "urn:schemas-upnp-org:service:AVTransport:1#Previous",}
  user = {xmlTag = 's:Body',{xmlTag = 'u:Previous' ,['xmlns:u'] = 'urn:schemas-upnp-org:service:AVTransport:1',{xmlTag = 'InstanceID',0 },{xmlTag = 'Speed',1 },}}  
  path = "/MediaRenderer/AVTransport/Control"
  body = {xmlTag = 's:Envelope',['xmlns:s'] = 'http://schemas.xmlsoap.org/soap/envelope/',['s:encodingStyle'] = 'http://schemas.xmlsoap.org/soap/encoding/',user}

Gate_HTTP->HttpRequest_post->SetPath(path)
Gate_HTTP->HttpRequest_post->SetRequestHeaders(header)
Gate_HTTP->HttpRequest_post->SetRequestBody(body)
Gate_HTTP->HttpRequest_post->SendRequest()
Gate_HTTP->sonos_state_get()

 


Powyższe skrypty będę potrzebne do zbudowania interfejsu w myGrenton, na którym zobaczyć można informację o aktualnie odtwarzanym utworze, uruchomić odtwarzanie, zatrzymać, przełączyć utwór.




Widżety Value konfigurujemy by pokazywały wskazana Cechę Wbudowaną 


Widżet sceny podwójnej do zmiany odtwarzanego utworu wywołuje skrypt, który realizuje daną komendę.



Widżet Value konfigurujemy aby pokazał wartość nagłośnienia