Integration with SONOS Mulitroom Systems

The purpose of this article is to present an example of the integration of the Sonos mulitroom system with the Grenton Smart Home System using Gate Http.



The mulitroom system used in this example is SONOS ONE

This integration allows us to receive the following information:

  • sound system control
  • Play, Pause, Next, Previous
  • read current track/album

To complete this example, we need:

  • CLU Z-Wave
  • Gate  http
  • SONOS smart speaker

Configuration

    1. Configure the Sonos speaker and connect it to the local network with CLU and Gate Http.
    2. Add two HttpRequest periphery objects (GET i POST).

  • Complete the values of the "HttpRequest_post" embedded features: 


Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/AVTransport/Control

Method: POST

RequestType: XML 

ResponseType: XML


  • Complete the values of the "HttpRequest_get_volume" embedded features: 

Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/RenderingControl/Control

Method: GET

RequestType: XML 

ResponseType: XML



Sound control


For smooth sound control, the information about the current volume value is needed. To do this, prepare a script that will execute the query for this value and pass it to the user feature. Below is a description of how to do it:


  • create a user feature in the Gate Http module, e.g. "SONOS_volume":

  • create a script called "Sonos_volume_get" that will query:
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()

 

  • create another script "Sonos_resp_volume", which will receive the value from the ResponseBody feature and pass its value to the "SONOS_volume":
local resp

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

 

Assign the script to the OnResponse event in the "HttpRequest_get_volume" periphery object:


Then, the configuration should be sent to the CLU.

After the configuration has been successfully sent, the "Sonos_volume_get" script should be called.

 

After calling the script, the StatusCode feature should receive the value 200:


and the "SONOS_volume" user features value should receive appropriate value:

    

When the sound value is known, it is possible to volume control. For this purpose, scripts that will increment, decrement or reset the Volume values are needed. Scripts can be done as follows:


  • create the "sonos_volume_up" script that perform the increment:
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()

 

  • create the script "sonos_volume_down" performs decrementation:
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()
  • create script "sonos_volume_mute" to mute the speaker:
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()

 

After sending the configuration to CLU, running the above-mentioned scripts will change the sound system.



Receiving information about a song, artist, album


To receive information about the currently playing song, album or artist, follow these steps:


  • Create "HttpRequest_get_info" HttpRequest periphery objects:

Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/AVTransport/Control

Method: GET

RequestType: XML 

ResponseType: XML


  • Create user features in the Gate Http module to which the information will be passed:

Where:

track - track title

artist - performer

duration - the length of the song

rel_time - duration of the track 

album - title of album


  • Create the "sonos_info_get" script:
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()
  • Create the "sonos_info_resp" script which will read the sent response:
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]

 


Assign the script to the OnResponse event in "HttpRequest_get_info" periphery object:


Then, the configuration should be sent to the CLU.

After the configuration has been successfully sent, the "sonos_info_get" script should be called.

 

After calling the script, the StatusCode feature should receive the value 200:

User features value should receive appropriate value:



Playback control (Play, Pause, Next, Previous)


To control the music being played (Play, Pause) the state of the speaker has to be known. To do this, follow the steps below:


  • create a user feature in the Gate Http module, e.g. "state":
  • create the HttpRequest periphery object named "HttpRequest_get_state":

Host: 192.168.7.175:1400 (adres IP SONOS)

Path:/MediaRenderer/AVTransport/Control

Method: GET

RequestType: XML 

ResponseType: XML


  • create the "sonos_state_get" script:
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()
  • create the "sonos_state_get_resp" script which will pass value to the user feature:
local resp

resp = Gate_HTTP->HttpRequest_get_state->ResponseBody
Gate_HTTP->state = resp[1][1][1][1]
  • Assign the script to the OnResponse event in "HttpRequest_get_state" periphery object:

Then, the configuration should be sent to the CLU.

After the configuration has been successfully sent, the "sonos_state_get" script should be called.

 

After calling the script, the StatusCode feature should receive the value 200:


the user feature value should receive appropriate value:


When the state of the speaker is known, it is possible to create scripts controlling the Play, Pause, Next, Previous functions. Scripts can be done as follows:


  • create the "sonos_play_pause" script:
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()
  • create the "sonos_next" script:
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()
  • create the "sonos_previous" script:
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()

 


These scripts are needed to build an interface in myGrenton where you can see information about the currently playing song, start playback, stop, switch songs.

 

To obtain the above interface, configure widgets like follows:

 

  • VALUE widgets:

 

  • SCENE widget:

 

  • DOUBLE SCENE widgets: