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żny 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ą inkrementacje, 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żny 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ł albumy


  • 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][5][1]
Gate_HTTP->album = didl[1][6][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()