TapHome

Sonos

Packet Parser → HTTP
Trimis de
Ultima actualizare: 10. 2026

Acest dispozitiv acceptă mDNS

În loc să folosiți o adresă IP, puteți accesa dispozitivul la:

Sonos-{MAC}.local

Înlocuiți {MAC} cu adresa MAC a dispozitivului dvs. (majuscule, fără două puncte).

TapHome acceptă mDNS — folosirea unui nume de gazdă este mai fiabilă decât un IP static.

Sonos

Sonos este un sistem audio wireless premium, conceput pentru redarea multiroom. TapHome comunică cu boxele Sonos în rețeaua locală prin UPnP/SOAP pe portul 1400, fără conexiune la cloud și fără autentificare. Șablonul este universal și funcționează cu toate modelele de boxe Sonos (Era 100, Era 300, One, Five, Beam, Arc, Ray, Move, Roam, Sub și altele).

Șablonul oferă controlul complet al redării (redare, pauză, stop, piesa următoare/anterioară), gestionarea volumului și a dezactivării sunetului, selectarea modului de redare, temporizatoare de oprire și până la 10 butoane presetate pentru playlisturi și posturi de radio. Un set de 14 atribute de service pune la dispoziție informații despre dispozitiv și piesa redată în acel moment.

Configurare

Boxa Sonos se conectează prin Wi-Fi. La importul șablonului în TapHome introduceți adresa IP a boxei (valoarea implicită: 192.168.0.1). Boxa trebuie să fie în aceeași rețea cu TapHome CCU.

Boxele Sonos acceptă descoperirea mDNS cu modelul de nume de gazdă Sonos-{MAC}.local (adresa MAC fără două puncte). Folosirea numelui de gazdă previne problemele de conectivitate când adresa IP a boxei se schimbă după o reînnoire DHCP.

Deschideți aplicația TapHome și folosiți Scanner IP (Setări → Rețea → Scanare). Scannerul descoperă dispozitivele din rețea și afișează atât adresa IP, cât și numele de gazdă mDNS (de ex. Sonos-B8E9375A1C02.local). Pentru o conexiune mai fiabilă folosiți numele de gazdă în locul adresei IP.

Funcțiile dispozitivului

Controlul volumului

Șablonul pune la dispoziție volumul ca dispozitiv de tip dimmer. Volumul se citește prin acțiunea SOAP RenderingControl GetVolume (interval 0–100) și se împarte la 100 pentru a obține valoarea dimmerului 0,0–1,0. Scrierea unui volum nou trimite SetVolume cu nivelul dorit. Volumul este interogat la fiecare 2,5 secunde.

Două butoane PushButton suplimentare, Creștere volum și Reducere volum, permit ajustarea relativă a volumului. Acestea sunt gestionate de logica din CCU, nu prin acțiuni SOAP directe, ceea ce permite integrarea cu întrerupătoare fizice de perete sau cu smart rules.

Dezactivarea sunetului

Dezactivarea sunetului este disponibilă ca întrerupător. Starea se citește prin GetMute și se scrie prin SetMute pe canalul Master. Când sunetul este dezactivat, ieșirea audio este oprită fără modificarea nivelului volumului.

Controlul redării

Șase butoane PushButton controlează redarea:

  • Play — trimite AVTransport Play (Speed=1)
  • Pauză — trimite AVTransport Pause
  • Stop — trimite AVTransport Stop
  • Piesa următoare — trimite AVTransport Next pentru a trece la piesa următoare
  • Piesa anterioară — trimite AVTransport Previous pentru a reveni la piesa anterioară
  • Play/Pauză — comută între redare și pauză în funcție de starea actuală a redării (gestionat de logica din CCU)
Starea redării

Un senzor binar doar pentru citire raportează dacă boxa redă în acel moment. Șablonul citește GetTransportInfo și asociază stările de redare: PLAYING și TRANSITIONING corespund valorii 1 (redare), iar STOPPED, NO_MEDIA_PRESENT și PAUSED_PLAYBACK valorii 0 (fără redare). Interogare la fiecare 2,5 secunde.

Modul de redare

Modul de redare este un comutator cu mai multe valori, cu șase moduri:

ValoareModDescriere
0NormalRedare secvențială
1Repetare toate pieseleRepetarea întregii cozi
2Repetare piesăRepetarea piesei curente
3Redare aleatorie fără repetareOrdine aleatorie fără repetare
4Redare aleatorieOrdine aleatorie cu repetare
5Redare aleatorie cu repetarea pieseiOrdine aleatorie, repetarea piesei curente

Valorile 6–9 sunt poziții suplimentare neutilizate în configurația cu mai multe valori și nu au nicio funcție.

Temporizatoare de oprire

Două butoane PushButton configurează temporizatoarele de oprire prin acțiunea AVTransport ConfigureSleepTimer:

  • Temporizator oprire (1 oră) — setează temporizatorul la 01:00:00
  • Temporizator oprire (15 min) — setează temporizatorul la 00:15:00

După expirarea temporizatorului, boxa oprește automat redarea.

Presetări pentru playlisturi și radio

Șablonul oferă 10 butoane PushButton presetate: 5 pentru playlisturi și 5 pentru posturi de radio. Fiecare buton are o variabilă a dispozitivului, pe care utilizatorul trebuie să o completeze cu numele playlistului sau al postului dorit. Scriptul se ocupă automat de căutare, de gestionarea cozii și de redare.

Playlisturi (butoanele 1–5): fiecare buton de playlist folosește variabila dispozitivului playlist_name. Scriptul caută în playlisturile Sonos ale boxei (Saved Queues) prin containerul ContentDirectory SQ:, după potrivirea exactă a dc:title (se ține cont de majuscule și minuscule). Când găsește o potrivire, scriptul golește coada curentă, adaugă playlistul în coadă și pornește redarea.

Configurarea unui buton de playlist:

  1. Deschideți aplicația TapHome → mergeți la dispozitivul playlistului → Variabilele dispozitivului
  2. Setați playlist_name la numele exact al unui playlist Sonos
  3. Crearea unui playlist Sonos: aplicația Sonos → adăugați piese în coadă → Save Queue as Playlist

Sunt acceptate doar playlisturile Sonos (Saved Queues). Un playlist Sonos poate conține piese de la majoritatea serviciilor de streaming: Apple Music, Tidal, Amazon Music, YouTube Music, Deezer și altele. Spotify este excepția: Spotify folosește o integrare proprietară, iar piesele sale nu pot fi adăugate în Saved Queues Sonos. Crearea unui playlist Sonos: deschideți aplicația Sonos, adăugați piesele dorite în coadă și salvați coada ca playlist.

Posturi de radio (butoanele 1–5): fiecare buton de radio folosește variabila dispozitivului radio_name. Scriptul caută în Sonos Favorites prin containerul ContentDirectory FV:2, după potrivirea exactă a dc:title (se ține cont de majuscule și minuscule), și filtrează după protocolul de radio în streaming (x-sonosapi-stream).

Configurarea unui buton de radio:

  1. Deschideți aplicația TapHome → mergeți la dispozitivul radio → Variabilele dispozitivului
  2. Setați radio_name la numele exact al postului, așa cum apare în Sonos Favorites
  3. Adăugarea unui post la Favorites: aplicația Sonos → navigați în TuneIn sau iHeartRadio → atingeți pictograma inimă/stea

Numele trebuie să corespundă exact (se ține cont de majuscule și minuscule). Deschideți aplicația Sonos, mergeți la My Sonos → Favorites și copiați numele postului caracter cu caracter. Sunt acceptate doar posturile de radio în streaming; conținutul audio la cerere din Favorites nu va funcționa.

Diagnosticare de service

Șablonul pune la dispoziție 14 atribute de service din fișierul XML de descriere a dispozitivului (/xml/device_description.xml):

  • Informații despre dispozitiv — numele modelului, URL-ul modelului, numărul de serie, adresa MAC, numele de gazdă, UDN (Unique Device Name)
  • Software — versiunea software, generația software, revizia hardware, versiunea API, versiunea API minimă
  • Configurare Sonos — numele camerei, numele afișat
  • Redare curentă — piesa curentă (titlu, artist, album extrase din metadatele DIDL-Lite prin GetPositionInfo)

Atributul piesei curente decodează datele TrackMetaData codificate în XML și returnează un șir pe mai multe rânduri cu titlul, artistul și albumul. Dacă metadatele nu sunt disponibile (de ex. la intrarea line-in), returnează „Not supported”.

Limitări

Șablonul controlează o singură boxă la un moment dat. Gruparea și degruparea zonelor multiroom nu sunt acceptate: pentru gestionarea grupurilor folosiți aplicația Sonos. Dacă o boxă face parte dintr-un grup, șablonul trebuie să indice coordonatorul grupului (consultați Rezolvarea problemelor mai jos).

Funcții suplimentare

API-ul UPnP Sonos pune la dispoziție 16 servicii, cu mai multe funcții decât cele implementate în prezent în șablon. Serviciul RenderingControl acceptă reglarea basului, a înaltelor și a funcției loudness, precum și modul de noapte la modelele soundbar. Serviciul AVTransport oferă controlul crossfade, derularea după timp sau după numărul piesei și gestionarea completă a cozii (adăugarea, eliminarea și reordonarea pieselor). Sunt disponibile și programarea alarmelor, setările EQ pentru configurațiile surround/subwoofer și starea bateriei la modelele portabile (Move, Roam). Aceste funcții pot fi adăugate într-o actualizare viitoare a șablonului.

Sonos trece treptat de la API-ul UPnP/SOAP (portul 1400) la un API REST local mai nou. La începutul anului 2026, UPnP rămâne complet funcțional pe toate modelele, inclusiv Era 100, Era 300 și Arc Ultra. Dacă Sonos restricționează UPnP într-o actualizare viitoare de firmware, șablonul ar putea necesita actualizarea pentru noul API.

Rezolvarea problemelor

Boxa nu răspunde
  1. Verificați dacă boxa Sonos este pornită și conectată la Wi-Fi
  2. Încercați să folosiți numele de gazdă mDNS (Sonos-{MAC}.local) în locul adresei IP: adresa IP s-ar putea să se fi schimbat după o reînnoire DHCP
  3. Deschideți http://{speaker-ip}:1400/xml/device_description.xml în browser: dacă răspunde cu XML, boxa este accesibilă
  4. Verificați dacă TapHome CCU și boxa Sonos sunt în aceeași rețea / VLAN
Comenzile de redare eșuează cu eroarea 800

Grupurile multiroom Sonos direcționează toate comenzile de redare prin coordonatorul grupului. Dacă șablonul se adresează unei boxe care nu este coordonatorul, comenzile de redare (Play, Pause, Next, Previous) vor eșua. Asigurați-vă că adresa IP din TapHome indică coordonatorul grupului sau scoateți boxa din grup, ca să devină un dispozitiv independent.

Modificările volumului nu se reflectă
  1. Confirmați că șablonul interoghează: volumul se citește la fiecare 2,5 secunde prin GetVolume
  2. Dacă un alt controler (aplicația Sonos, Apple AirPlay) a modificat volumul, TapHome va prelua noua valoare la următorul ciclu de interogare
  3. Verificați dacă boxa nu face parte dintr-un grup în care volumul este controlat de coordonatorul grupului

Boxele Sonos acceptă comenzi UPnP doar de la dispozitive din aceeași subrețea. Dacă TapHome CCU este într-un alt VLAN, asigurați-vă că traficul multicast/UPnP este rutat între VLAN-uri sau plasați ambele dispozitive în același segment de rețea.

Dispozitive disponibile

Sonos Modul
Atribute de service
Nume model
URL model
Versiune SW
Generație SW
Revizie HW
Număr de serie
Adresă MAC
Nume de gazdă
UDN
Versiune API
Versiune API minimă
Nume cameră
Nume afișat
Piesa curentă
Variabile personalizate
deviceDescription (string)

Sonos

Atribute de service
Model name
VAR response := SENDHTTPREQUEST("/xml/device_description.xml");
deviceDescription := response.Content;

PARSEXML(deviceDescription, "//root:modelName[1]");
Model url
PARSEXML(deviceDescription, "//root:modelURL[1]");
SW version
PARSEXML(deviceDescription, "//root:softwareVersion[1]");
SW generation
PARSEXML(deviceDescription, "//root:swGen[1]");
HW revision
PARSEXML(deviceDescription, "//root:hardwareVersion[1]");
Serial number
PARSEXML(deviceDescription, "//root:serialNum[1]");
Mac address
PARSEXML(deviceDescription, "//root:MACAddress[1]");
Host name
VAR macAddress := PARSEXML(deviceDescription, "//root:MACAddress[1]");
"Sonos-" + REPLACE(macAddress, ":", "") + ".local"
UDN
PARSEXML(deviceDescription, "//root:UDN[1]");
API version
PARSEXML(deviceDescription, "//root:apiVersion[1]");
Min API version
PARSEXML(deviceDescription, "//root:minApiVersion[1]");
Room name
PARSEXML(deviceDescription, "//root:roomName[1]");
Display name
PARSEXML(deviceDescription, "//root:displayName[1]");
Current track
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:GetPositionInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetPositionInfo></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);

IF response.IsSuccess
    VAR responseXml := response.Content;
    VAR metaData := DECODE(PARSETEXT(responseXml, "<TrackMetaData>", "</TrackMetaData>"), "xml");
    
    IF(metaData = "NOT_IMPLEMENTED")
        RETURN("Not supported");
    END

    IF(LENGTH(metaData) = 0)
        RETURN("");
    END

    VAR title := PARSEXML(metaData, "//dc:title");
    VAR artist := PARSEXML(metaData, "//dc:creator");
    VAR album := PARSEXML(metaData, "//upnp:album");
    
    VAR result := "";
    
    IF(LENGTH(title) > 0)
        result := "Title: " + title + "\n";
    END
    
    IF(LENGTH(artist) > 0)
         result := result + "Artist: " + artist + "\n";
    END
    
    IF(LENGTH(album) > 0)
        result := result + "Album: " + album;
    END

    RETURN(result);
ELSE
    RETURN("Error");
END
Volum Dimmer
numeric Unitate: %

Volum

Citirea nivelului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#GetVolume\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:GetVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel></u:GetVolume></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/RenderingControl/Control", "POST", body, header);

IF response.IsSuccess
    VAR responseXml := response.Content;
    RETURN(PARSEXML(responseXml, "//CurrentVolume") / 100.0);
ELSE
    ADDERROR(response.Content);
    RETURN(NaN);
END
Scrierea nivelului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#SetVolume\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:SetVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>" + ROUND(Le*100) + "</DesiredVolume></u:SetVolume></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/RenderingControl/Control", "POST", body, header);
Piesa următoare Buton
action

Piesa următoare

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Next\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Next xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Next></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Pauză Buton
action

Pauză

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Pause\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Pause xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Pause></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Play Buton
action

Play

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Piesa anterioară Buton
action

Piesa anterioară

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Previous\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Previous xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Previous></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Stop Buton
action

Stop

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Stop\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Stop xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Stop></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Creștere volum Buton
action

Creștere volum

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#SetRelativeVolume\"";

VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:SetRelativeVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel><Adjustment>5</Adjustment></u:SetRelativeVolume></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/RenderingControl/Control", "POST", body, header);
Reducere volum Buton
action

Reducere volum

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#SetRelativeVolume\"";

VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:SetRelativeVolume xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel><Adjustment>-5</Adjustment></u:SetRelativeVolume></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/RenderingControl/Control", "POST", body, header);
Dezactivare sunet Comutator
boolean
Valori / Stări: ON · OFF

Dezactivare sunet

Citirea stării comutatorului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#GetMute\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:GetMute xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel></u:GetMute></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/RenderingControl/Control", "POST", body, header);

IF response.IsSuccess
    VAR responseXml := response.Content;
    RETURN(PARSEXML(responseXml, "//CurrentMute"));
ELSE
    ADDERROR(response.Content);
    RETURN(NaN);
END
Scrierea stării comutatorului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:RenderingControl:1#SetMute\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:SetMute xmlns:u=\"urn:schemas-upnp-org:service:RenderingControl:1\"><InstanceID>0</InstanceID><Channel>Master</Channel><DesiredMute>" + St + "</DesiredMute></u:SetMute></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/RenderingControl/Control", "POST", body, header);
Mod de redare Comutator cu mai multe valori
enum mapped
Valori / Stări: Normal · Repeat all · Repeat one · Shuffle no repeat · Shuffle · Shuffle repeat one

Mod de redare

Citirea stării comutatorului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetTransportSettings\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:GetTransportSettings xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetTransportSettings></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);

IF response.IsSuccess
    VAR responseXml := response.Content;
    VAR mode := PARSEXML(responseXml, "//PlayMode");
    RETURN(SWITCH(mode , "NORMAL", 0, "REPEAT_ALL", 1, "REPEAT_ONE", 2, "SHUFFLE_NOREPEAT", 3, "SHUFFLE", 4, "SHUFFLE_REPEAT_ONE", 5, -1));
ELSE
    ADDERROR(response.Content);
    RETURN(NaN);
END
Scrierea stării comutatorului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetPlayMode\"";

VAR mode := SWITCH(Mu, 0, "NORMAL", 1, "REPEAT_ALL", 2, "REPEAT_ONE", 3, "SHUFFLE_NOREPEAT", 4, "SHUFFLE", 5, "SHUFFLE_REPEAT_ONE", "NORMAL");

VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:SetPlayMode xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><NewPlayMode>" + mode +"</NewPlayMode></u:SetPlayMode></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Oprire peste 1 oră Buton
action

Oprire peste 1 oră

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#ConfigureSleepTimer\"";

VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:ConfigureSleepTimer xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><NewSleepTimerDuration>01:00:00</NewSleepTimerDuration></u:ConfigureSleepTimer></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Oprire peste 15 min Buton
action

Oprire peste 15 min

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#ConfigureSleepTimer\"";

VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:ConfigureSleepTimer xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><NewSleepTimerDuration>00:15:00</NewSleepTimerDuration></u:ConfigureSleepTimer></s:Body></s:Envelope>";

SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
Starea redării Contact reed Doar citire
boolean mapped

Starea redării

Citire
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:GetTransportInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetTransportInfo></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);

IF response.IsSuccess
    VAR responseXml := response.Content;
    VAR state := PARSEXML(responseXml, "//CurrentTransportState");
    RETURN(SWITCH(state , "PLAYING", 1, "TRANSITIONING", 1, "STOPPED", 0, "NO_MEDIA_PRESENT", 0, "PAUSED_PLAYBACK", 0, 0));
ELSE
    ADDERROR(response.Content);
    RETURN(NaN);
END
Play/Pauză Buton
action

Play/Pauză

Scrierea stării butonului
VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo\"";
VAR body := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:GetTransportInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:GetTransportInfo></s:Body></s:Envelope>";

VAR response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);

IF response.IsSuccess
    VAR responseXml := response.Content;
    VAR state := PARSEXML(responseXml, "//CurrentTransportState");
    VAR isPlaying := SWITCH(state , "PLAYING", 1, "TRANSITIONING", 1, "STOPPED", 0, "NO_MEDIA_PRESENT", 0, "PAUSED_PLAYBACK", 0, 0);
    
    IF(isPlaying)
        VAR headerPause := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Pause\"";
        VAR bodyPause := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Pause xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:Pause></s:Body></s:Envelope>";

        SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", bodyPause, headerPause);
    ELSE
        VAR headerPlay := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
        VAR bodyPlay := "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

        SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", bodyPlay, headerPlay);
    END
ELSE
    ADDERROR(response.Content);
    RETURN(NaN);
END
Playlist 1 Buton
action
Variabilă: playlist_name — Numele exact al unui playlist Sonos (Saved Queue). Se ține cont de majuscule și minuscule.

Playlist 1

Scrierea stării butonului
######################
# check playlist name is not empty
IF(ISNULL(playlist_name) OR LENGTH(playlist_name) = 0)
   ADDERROR("Please set playlist name in device variables");
   RETURN(-1);
END

######################
# get player uuid
VAR response := SENDHTTPREQUEST("xml/device_description.xml");
VAR content := response.Content;
VAR playerUuid := PARSETEXT(content, "<UDN>uuid:", "</UDN>");

IF(ISNULL(playerUuid))
    ADDERROR("Failed to get player UUID");
    RETURN(-2);
END
######################

######################
# fetch playlists
VAR playlistUri := NULL;
VAR numberOfPlaylists := -1;
VAR readPlaylists := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>SQ:</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readPlaylists + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    content := response.Content;
    
    IF(numberOfPlaylists = -1)
        numberOfPlaylists := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedPlaylists := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readPlaylists := readPlaylists + returnedPlaylists;
    
    VAR playlistsXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    playlistUri := PARSEXML(playlistsXml, "//DIDL-Lite:container[dc:title='" + playlist_name + "']/DIDL-Lite:res");
    
    IF(!ISNULL(playlistUri) AND LENGTH(playlistUri) > 0)
        BREAK;
    END
LOOP WHILE readPlaylists < numberOfPlaylists
    
######################
IF(ISNULL(playlistUri) OR LENGTH(playlistUri) = 0)
    ADDERROR("Unable to find playlist with name '" + playlist_name + "'. Only Sonos playlists are supported.");
    RETURN(-3);
END

######################
# clear play queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#RemoveAllTracksFromQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:RemoveAllTracksFromQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:RemoveAllTracksFromQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to RemoveAllTracksFromQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-4);
END
######################

######################
# add playlist to queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddURIToQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><EnqueuedURI>" + playlistUri + "</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>0</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to AddURIToQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-5);
END
######################

######################
# set play uri
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>x-rincon-queue:" + playerUuid + "#0</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-6);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-7);
END
######################
Playlist 2 Buton
action
Variabilă: playlist_name — Numele exact al unui playlist Sonos (Saved Queue). Se ține cont de majuscule și minuscule.

Playlist 2

Scrierea stării butonului
######################
# check playlist name is not empty
IF(ISNULL(playlist_name) OR LENGTH(playlist_name) = 0)
   ADDERROR("Please set playlist name in device variables");
   RETURN(-1);
END

######################
# get player uuid
VAR response := SENDHTTPREQUEST("xml/device_description.xml");
VAR content := response.Content;
VAR playerUuid := PARSETEXT(content, "<UDN>uuid:", "</UDN>");

IF(ISNULL(playerUuid))
    ADDERROR("Failed to get player UUID");
    RETURN(-2);
END
######################

######################
# fetch playlists
VAR playlistUri := NULL;
VAR numberOfPlaylists := -1;
VAR readPlaylists := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>SQ:</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readPlaylists + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    content := response.Content;
    
    IF(numberOfPlaylists = -1)
        numberOfPlaylists := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedPlaylists := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readPlaylists := readPlaylists + returnedPlaylists;
    
    VAR playlistsXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    playlistUri := PARSEXML(playlistsXml, "//DIDL-Lite:container[dc:title='" + playlist_name + "']/DIDL-Lite:res");
    
    IF(!ISNULL(playlistUri) AND LENGTH(playlistUri) > 0)
        BREAK;
    END
LOOP WHILE readPlaylists < numberOfPlaylists
    
######################
IF(ISNULL(playlistUri) OR LENGTH(playlistUri) = 0)
    ADDERROR("Unable to find playlist with name '" + playlist_name + "'. Only Sonos playlists are supported.");
    RETURN(-3);
END

######################
# clear play queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#RemoveAllTracksFromQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:RemoveAllTracksFromQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:RemoveAllTracksFromQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to RemoveAllTracksFromQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-4);
END
######################

######################
# add playlist to queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddURIToQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><EnqueuedURI>" + playlistUri + "</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>0</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to AddURIToQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-5);
END
######################

######################
# set play uri
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>x-rincon-queue:" + playerUuid + "#0</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-6);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-7);
END
######################
Playlist 3 Buton
action
Variabilă: playlist_name — Numele exact al unui playlist Sonos (Saved Queue). Se ține cont de majuscule și minuscule.

Playlist 3

Scrierea stării butonului
######################
# check playlist name is not empty
IF(ISNULL(playlist_name) OR LENGTH(playlist_name) = 0)
   ADDERROR("Please set playlist name in device variables");
   RETURN(-1);
END

######################
# get player uuid
VAR response := SENDHTTPREQUEST("xml/device_description.xml");
VAR content := response.Content;
VAR playerUuid := PARSETEXT(content, "<UDN>uuid:", "</UDN>");

IF(ISNULL(playerUuid))
    ADDERROR("Failed to get player UUID");
    RETURN(-2);
END
######################

######################
# fetch playlists
VAR playlistUri := NULL;
VAR numberOfPlaylists := -1;
VAR readPlaylists := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>SQ:</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readPlaylists + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    content := response.Content;
    
    IF(numberOfPlaylists = -1)
        numberOfPlaylists := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedPlaylists := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readPlaylists := readPlaylists + returnedPlaylists;
    
    VAR playlistsXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    playlistUri := PARSEXML(playlistsXml, "//DIDL-Lite:container[dc:title='" + playlist_name + "']/DIDL-Lite:res");
    
    IF(!ISNULL(playlistUri) AND LENGTH(playlistUri) > 0)
        BREAK;
    END
LOOP WHILE readPlaylists < numberOfPlaylists
    
######################
IF(ISNULL(playlistUri) OR LENGTH(playlistUri) = 0)
    ADDERROR("Unable to find playlist with name '" + playlist_name + "'. Only Sonos playlists are supported.");
    RETURN(-3);
END

######################
# clear play queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#RemoveAllTracksFromQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:RemoveAllTracksFromQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:RemoveAllTracksFromQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to RemoveAllTracksFromQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-4);
END
######################

######################
# add playlist to queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddURIToQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><EnqueuedURI>" + playlistUri + "</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>0</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to AddURIToQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-5);
END
######################

######################
# set play uri
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>x-rincon-queue:" + playerUuid + "#0</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-6);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-7);
END
######################
Playlist 4 Buton
action
Variabilă: playlist_name — Numele exact al unui playlist Sonos (Saved Queue). Se ține cont de majuscule și minuscule.

Playlist 4

Scrierea stării butonului
######################
# check playlist name is not empty
IF(ISNULL(playlist_name) OR LENGTH(playlist_name) = 0)
   ADDERROR("Please set playlist name in device variables");
   RETURN(-1);
END

######################
# get player uuid
VAR response := SENDHTTPREQUEST("xml/device_description.xml");
VAR content := response.Content;
VAR playerUuid := PARSETEXT(content, "<UDN>uuid:", "</UDN>");

IF(ISNULL(playerUuid))
    ADDERROR("Failed to get player UUID");
    RETURN(-2);
END
######################

######################
# fetch playlists
VAR playlistUri := NULL;
VAR numberOfPlaylists := -1;
VAR readPlaylists := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>SQ:</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readPlaylists + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    content := response.Content;
    
    IF(numberOfPlaylists = -1)
        numberOfPlaylists := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedPlaylists := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readPlaylists := readPlaylists + returnedPlaylists;
    
    VAR playlistsXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    playlistUri := PARSEXML(playlistsXml, "//DIDL-Lite:container[dc:title='" + playlist_name + "']/DIDL-Lite:res");
    
    IF(!ISNULL(playlistUri) AND LENGTH(playlistUri) > 0)
        BREAK;
    END
LOOP WHILE readPlaylists < numberOfPlaylists
    
######################
IF(ISNULL(playlistUri) OR LENGTH(playlistUri) = 0)
    ADDERROR("Unable to find playlist with name '" + playlist_name + "'. Only Sonos playlists are supported.");
    RETURN(-3);
END

######################
# clear play queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#RemoveAllTracksFromQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:RemoveAllTracksFromQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:RemoveAllTracksFromQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to RemoveAllTracksFromQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-4);
END
######################

######################
# add playlist to queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddURIToQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><EnqueuedURI>" + playlistUri + "</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>0</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to AddURIToQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-5);
END
######################

######################
# set play uri
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>x-rincon-queue:" + playerUuid + "#0</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-6);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-7);
END
######################
Playlist 5 Buton
action
Variabilă: playlist_name — Numele exact al unui playlist Sonos (Saved Queue). Se ține cont de majuscule și minuscule.

Playlist 5

Scrierea stării butonului
######################
# check playlist name is not empty
IF(ISNULL(playlist_name) OR LENGTH(playlist_name) = 0)
   ADDERROR("Please set playlist name in device variables");
   RETURN(-1);
END

######################
# get player uuid
VAR response := SENDHTTPREQUEST("xml/device_description.xml");
VAR content := response.Content;
VAR playerUuid := PARSETEXT(content, "<UDN>uuid:", "</UDN>");

IF(ISNULL(playerUuid))
    ADDERROR("Failed to get player UUID");
    RETURN(-2);
END
######################

######################
# fetch playlists
VAR playlistUri := NULL;
VAR numberOfPlaylists := -1;
VAR readPlaylists := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>SQ:</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readPlaylists + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    content := response.Content;
    
    IF(numberOfPlaylists = -1)
        numberOfPlaylists := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedPlaylists := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readPlaylists := readPlaylists + returnedPlaylists;
    
    VAR playlistsXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    playlistUri := PARSEXML(playlistsXml, "//DIDL-Lite:container[dc:title='" + playlist_name + "']/DIDL-Lite:res");
    
    IF(!ISNULL(playlistUri) AND LENGTH(playlistUri) > 0)
        BREAK;
    END
LOOP WHILE readPlaylists < numberOfPlaylists
    
######################
IF(ISNULL(playlistUri) OR LENGTH(playlistUri) = 0)
    ADDERROR("Unable to find playlist with name '" + playlist_name + "'. Only Sonos playlists are supported.");
    RETURN(-3);
END

######################
# clear play queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#RemoveAllTracksFromQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:RemoveAllTracksFromQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID></u:RemoveAllTracksFromQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to RemoveAllTracksFromQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-4);
END
######################

######################
# add playlist to queue
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddURIToQueue xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><EnqueuedURI>" + playlistUri + "</EnqueuedURI><EnqueuedURIMetaData></EnqueuedURIMetaData><DesiredFirstTrackNumberEnqueued>0</DesiredFirstTrackNumberEnqueued><EnqueueAsNext>0</EnqueueAsNext></u:AddURIToQueue></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to AddURIToQueue (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-5);
END
######################

######################
# set play uri
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>x-rincon-queue:" + playerUuid + "#0</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-6);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
    ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
    RETURN(-7);
END
######################
Post de radio 1 Buton
action
Variabilă: radio_name — Numele exact al unui post de radio din Sonos Favorites. Se ține cont de majuscule și minuscule.

Post de radio 1

Scrierea stării butonului
######################
# check radio name is not empty
IF(ISNULL(radio_name) OR LENGTH(radio_name) = 0)
   ADDERROR("Please set radio name in device variables");
   RETURN(-1);
END

######################
# fetch favorites
VAR radioUri := NULL;
VAR numberOfFavorites := -1;
VAR readFavorites := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>FV:2</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readFavorites + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    VAR response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    VAR content := response.Content;
   
    IF(numberOfFavorites = -1)
        numberOfFavorites := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedFavorites := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readFavorites := readFavorites + returnedFavorites;
    
    VAR favoritesXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    radioUri := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "']/DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']");
    
    IF(!ISNULL(radioUri) AND LENGTH(radioUri) > 0)
        BREAK;
    END
LOOP WHILE readFavorites < numberOfFavorites

IF(ISNULL(radioUri) OR LENGTH(radioUri) = 0)
    ADDERROR("Unable to find radio with name '" + radio_name + "'. Make sure it's included in your Sonos favorite radio stations");
    RETURN(-3);
END

######################
# find radio metadata
VAR radioMetaData := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "'and DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']]/r:resMD");

IF(ISNULL(radioMetaData) OR LENGTH(radioMetaData) = 0)
	ADDERROR("Unable to find radio metadata");
	RETURN(-4);
END

######################
# set radio uri
VAR metaDataEncoded := ENCODE(radioMetaData, "xml");
VAR uriEncoded := ENCODE(radioUri, "xml");

header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>" + uriEncoded + "</CurrentURI><CurrentURIMetaData>" + metaDataEncoded + "</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-5);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-6);
END
######################
Post de radio 2 Buton
action
Variabilă: radio_name — Numele exact al unui post de radio din Sonos Favorites. Se ține cont de majuscule și minuscule.

Post de radio 2

Scrierea stării butonului
######################
# check radio name is not empty
IF(ISNULL(radio_name) OR LENGTH(radio_name) = 0)
   ADDERROR("Please set radio name in device variables");
   RETURN(-1);
END

######################
# fetch favorites
VAR radioUri := NULL;
VAR numberOfFavorites := -1;
VAR readFavorites := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>FV:2</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readFavorites + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    VAR response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    VAR content := response.Content;
   
    IF(numberOfFavorites = -1)
        numberOfFavorites := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedFavorites := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readFavorites := readFavorites + returnedFavorites;
    
    VAR favoritesXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    radioUri := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "']/DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']");
    
    IF(!ISNULL(radioUri) AND LENGTH(radioUri) > 0)
        BREAK;
    END
LOOP WHILE readFavorites < numberOfFavorites

IF(ISNULL(radioUri) OR LENGTH(radioUri) = 0)
    ADDERROR("Unable to find radio with name '" + radio_name + "'. Make sure it's included in your Sonos favorite radio stations");
    RETURN(-3);
END

######################
# find radio metadata
VAR radioMetaData := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "'and DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']]/r:resMD");

IF(ISNULL(radioMetaData) OR LENGTH(radioMetaData) = 0)
	ADDERROR("Unable to find radio metadata");
	RETURN(-4);
END

######################
# set radio uri
VAR metaDataEncoded := ENCODE(radioMetaData, "xml");
VAR uriEncoded := ENCODE(radioUri, "xml");

header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>" + uriEncoded + "</CurrentURI><CurrentURIMetaData>" + metaDataEncoded + "</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-5);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-6);
END
######################
Post de radio 3 Buton
action
Variabilă: radio_name — Numele exact al unui post de radio din Sonos Favorites. Se ține cont de majuscule și minuscule.

Post de radio 3

Scrierea stării butonului
######################
# check radio name is not empty
IF(ISNULL(radio_name) OR LENGTH(radio_name) = 0)
   ADDERROR("Please set radio name in device variables");
   RETURN(-1);
END

######################
# fetch favorites
VAR radioUri := NULL;
VAR numberOfFavorites := -1;
VAR readFavorites := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>FV:2</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readFavorites + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    VAR response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    VAR content := response.Content;
   
    IF(numberOfFavorites = -1)
        numberOfFavorites := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedFavorites := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readFavorites := readFavorites + returnedFavorites;
    
    VAR favoritesXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    radioUri := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "']/DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']");
    
    IF(!ISNULL(radioUri) AND LENGTH(radioUri) > 0)
        BREAK;
    END
LOOP WHILE readFavorites < numberOfFavorites

IF(ISNULL(radioUri) OR LENGTH(radioUri) = 0)
    ADDERROR("Unable to find radio with name '" + radio_name + "'. Make sure it's included in your Sonos favorite radio stations");
    RETURN(-3);
END

######################
# find radio metadata
VAR radioMetaData := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "'and DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']]/r:resMD");

IF(ISNULL(radioMetaData) OR LENGTH(radioMetaData) = 0)
	ADDERROR("Unable to find radio metadata");
	RETURN(-4);
END

######################
# set radio uri
VAR metaDataEncoded := ENCODE(radioMetaData, "xml");
VAR uriEncoded := ENCODE(radioUri, "xml");

header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>" + uriEncoded + "</CurrentURI><CurrentURIMetaData>" + metaDataEncoded + "</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-5);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-6);
END
######################
Post de radio 4 Buton
action
Variabilă: radio_name — Numele exact al unui post de radio din Sonos Favorites. Se ține cont de majuscule și minuscule.

Post de radio 4

Scrierea stării butonului
######################
# check radio name is not empty
IF(ISNULL(radio_name) OR LENGTH(radio_name) = 0)
   ADDERROR("Please set radio name in device variables");
   RETURN(-1);
END

######################
# fetch favorites
VAR radioUri := NULL;
VAR numberOfFavorites := -1;
VAR readFavorites := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>FV:2</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readFavorites + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    VAR response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    VAR content := response.Content;
   
    IF(numberOfFavorites = -1)
        numberOfFavorites := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedFavorites := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readFavorites := readFavorites + returnedFavorites;
    
    VAR favoritesXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    radioUri := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "']/DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']");
    
    IF(!ISNULL(radioUri) AND LENGTH(radioUri) > 0)
        BREAK;
    END
LOOP WHILE readFavorites < numberOfFavorites

IF(ISNULL(radioUri) OR LENGTH(radioUri) = 0)
    ADDERROR("Unable to find radio with name '" + radio_name + "'. Make sure it's included in your Sonos favorite radio stations");
    RETURN(-3);
END

######################
# find radio metadata
VAR radioMetaData := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "'and DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']]/r:resMD");

IF(ISNULL(radioMetaData) OR LENGTH(radioMetaData) = 0)
	ADDERROR("Unable to find radio metadata");
	RETURN(-4);
END

######################
# set radio uri
VAR metaDataEncoded := ENCODE(radioMetaData, "xml");
VAR uriEncoded := ENCODE(radioUri, "xml");

header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>" + uriEncoded + "</CurrentURI><CurrentURIMetaData>" + metaDataEncoded + "</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-5);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-6);
END
######################
Post de radio 5 Buton
action
Variabilă: radio_name — Numele exact al unui post de radio din Sonos Favorites. Se ține cont de majuscule și minuscule.

Post de radio 5

Scrierea stării butonului
######################
# check radio name is not empty
IF(ISNULL(radio_name) OR LENGTH(radio_name) = 0)
   ADDERROR("Please set radio name in device variables");
   RETURN(-1);
END

######################
# fetch favorites
VAR radioUri := NULL;
VAR numberOfFavorites := -1;
VAR readFavorites := 0;

DO
    VAR header := "SOAPACTION: \"urn:schemas-upnp-org:service:ContentDirectory:1#Browse\"";
    VAR body := "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><u:Browse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\"><ObjectID>FV:2</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter></Filter><StartingIndex>" + readFavorites + "</StartingIndex><RequestedCount>10</RequestedCount><SortCriteria></SortCriteria></u:Browse></s:Body></s:Envelope>";

    VAR response := SENDHTTPREQUEST("MediaServer/ContentDirectory/Control", "POST", body, header);
    VAR content := response.Content;
   
    IF(numberOfFavorites = -1)
        numberOfFavorites := TODOUBLE(PARSETEXT(content, "<TotalMatches>", "</TotalMatches>"));
    END
    
    VAR returnedFavorites := TODOUBLE(PARSETEXT(content, "<NumberReturned>", "</NumberReturned>"));
    readFavorites := readFavorites + returnedFavorites;
    
    VAR favoritesXml := DECODE(PARSETEXT(content, "<Result>", "</Result>"), "xml");
    radioUri := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "']/DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']");
    
    IF(!ISNULL(radioUri) AND LENGTH(radioUri) > 0)
        BREAK;
    END
LOOP WHILE readFavorites < numberOfFavorites

IF(ISNULL(radioUri) OR LENGTH(radioUri) = 0)
    ADDERROR("Unable to find radio with name '" + radio_name + "'. Make sure it's included in your Sonos favorite radio stations");
    RETURN(-3);
END

######################
# find radio metadata
VAR radioMetaData := PARSEXML(favoritesXml, "//DIDL-Lite:item[dc:title='" + radio_name + "'and DIDL-Lite:res[@protocolInfo='x-sonosapi-stream:*:*:*']]/r:resMD");

IF(ISNULL(radioMetaData) OR LENGTH(radioMetaData) = 0)
	ADDERROR("Unable to find radio metadata");
	RETURN(-4);
END

######################
# set radio uri
VAR metaDataEncoded := ENCODE(radioMetaData, "xml");
VAR uriEncoded := ENCODE(radioUri, "xml");

header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetAVTransportURI xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><CurrentURI>" + uriEncoded + "</CurrentURI><CurrentURIMetaData>" + metaDataEncoded + "</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to SetAVTransportURI (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-5);
END
######################

######################
# play
header := "SOAPACTION: \"urn:schemas-upnp-org:service:AVTransport:1#Play\"";
body := "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>";

response := SENDHTTPREQUEST("MediaRenderer/AVTransport/Control", "POST", body, header);
IF(!response.IsSuccess)
	ADDERROR("Unable to Play (" + PARSEJSON(response, "Content", 1) + ")");
	RETURN(-6);
END
######################
Conexiune: Packet Parser → HTTP • Nume gazdă: Sonos-{MAC}.local
Îmbunătățiri posibile (14)
  • Bass control — Adjustable bass level -10 to 10
  • Treble control — Adjustable treble level -10 to 10
  • Loudness compensation — Boolean loudness on/off
  • Night mode — Boolean night mode (reduced dynamics), available on soundbar models
  • Crossfade — Boolean crossfade on/off between tracks
  • Seek (time/track) — Seek by TRACK_NR, REL_TIME, or TIME_DELTA
  • Queue management — Full queue CRUD — add, remove, reorder tracks
  • Group management — Multi-room group join/leave/delegate coordinator
  • Alarm management — Create, edit, delete alarms on the speaker
  • Battery status — Battery data available on portable models only (Move, Roam)
  • Relative volume — Increment/decrement volume by delta value
  • Sleep timer remaining — Read remaining sleep timer duration (hh:mm:ss)
  • Surround/Sub EQ — Subwoofer gain, surround level, height channel — available on multi-speaker setups
  • LED control — Status LED on/off

Surse

Ați găsit o problemă la acest șablon de dispozitiv?

Spuneți-ne ce nu funcționează, ce lipsește sau cum ar trebui să se comporte șablonul. Feedbackul dvs. ne ajută să păstrăm catalogul corect.

Verificat de TapHome

Doriți să folosiți acest șablon în TapHome Core?

Deschideți acest șablon în Customer Portal pentru a-l aplica într-una dintre locuințele dvs. sau pentru a propune o îmbunătățire și a o trimite înapoi în catalog.

Deschideți în portal