source: trunk/J_Sonos1.js @ 139

Revision 139, 41.7 KB checked in by lolodomo, 11 years ago (diff)

New: playback of a Sirius station with the following URI format in PlayURI command: SR:<stationID>

  • Property svn:executable set to *
  • Property svn:keywords set to Id
Line 
1//
2// $Id$
3//
4var Sonos_timeoutVar = undefined;
5var Sonos_timeoutVar2 = undefined;
6var Sonos_browserIE = false
7var Sonos_parseXml = undefined;
8
9var Sonos_prevGroups = undefined;
10var Sonos_prevSavedQueues = undefined;
11var Sonos_prevQueue = undefined;
12var Sonos_prevFavRadios = undefined;
13var Sonos_prevCoordinator = undefined;
14var Sonos_prevOnlineState = undefined;
15var Sonos_prevCurrentAlbumArtUrl = undefined;
16var Sonos_prevTitle = undefined;
17var Sonos_prevAlbum = undefined;
18var Sonos_prevArtist = undefined;
19var Sonos_prevDetails = undefined;
20var Sonos_prevCurrentTrack = undefined;
21var Sonos_prevNbrTracks = undefined;
22var Sonos_prevPlaying = undefined;
23var Sonos_prevActions = undefined;
24var Sonos_prevTransportUri = undefined;
25var Sonos_prevCurrentService = undefined;
26var Sonos_prevCurrentRadio = undefined;
27var Sonos_prevMute = undefined;
28var Sonos_prevVolume = undefined;
29
30var Sonos_prevModelName = undefined;
31var Sonos_prevIp = undefined;
32var Sonos_prevZone = undefined;
33var Sonos_prevOnlineState2 = undefined;
34var Sonos_prevProxy = undefined;
35var Sonos_prevResultDiscovery = undefined;
36
37var SONOS_SID = 'urn:micasaverde-com:serviceId:Sonos1';
38var AVTRANSPORT_SID = 'urn:upnp-org:serviceId:AVTransport';
39var RENDERING_CONTROL_SID = 'urn:upnp-org:serviceId:RenderingControl';
40var MEDIA_NAVIGATION_SID = 'urn:micasaverde-com:serviceId:MediaNavigation1';
41var VOLUME_SID = 'urn:micasaverde-com:serviceId:Volume1';
42var DEVICE_PROPERTIES_SID = 'urn:upnp-org:serviceId:DeviceProperties';
43var ZONEGROUPTOPOLOGY_SID = 'urn:upnp-org:serviceId:ZoneGroupTopology';
44var CONTENT_DIRECTORY_SID = 'urn:upnp-org:serviceId:ContentDirectory';
45
46function Sonos_showPlayer(device)
47{
48    if (typeof Sonos_timeoutVar != 'undefined') {
49        clearTimeout(Sonos_timeoutVar);
50    }
51
52    Sonos_detectBrowser();
53
54    Sonos_initXMLParser();
55
56    var html = '';
57
58    html += '<table>';
59    html += '<tr>';
60    html += '<td rowspan=6><img id="albumArt" width="100" height="100"/></td>';
61    html += '<td id="service"></td>';
62    html += '<td id="radio"></td>';
63    html += '</tr>';
64    html += '<tr>';
65    html += '<td id="trackLabel">Track:</td>';
66    html += '<td id="track"></td>';
67    html += '</tr>';
68    html += '<tr>';
69    html += '<td id="artistLabel">Artist:</td>';
70    html += '<td id="artist"></td>';
71    html += '</tr>';
72    html += '<tr>';
73    html += '<td id="albumLabel">Album:</td>';
74    html += '<td id="album"></td>';
75    html += '</tr>';
76    html += '<tr>';
77    html += '<td id="titleLabel">Track title:</td>';
78    html += '<td id="title"></td>';
79    html += '</tr>';
80    html += '<tr>';
81    html += '<td id="detailsLabel"></td>';
82    html += '<td id="details"></td>';
83    html += '</tr>';
84    html += '</table>';
85    html += '<DIV>'
86    html += '<table>';
87    html += '<tr>';
88    html += '<td>';
89    html += '<button id="prevTrack" type="button" style="background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_prevTrack('+device+');">Prev</button>';
90    html += '</td>';
91    html += '<td>';
92    html += '<button id="play" type="button" style="background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_play('+device+');">Play</button>';
93    html += '</td>';
94    html += '<td>';
95    html += '<button id="pause" type="button" style="background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_pause('+device+');">Pause</button>';
96    html += '</td>';
97    html += '<td>';
98    html += '<button id="stop" type="button" style="background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_stop('+device+');">Stop</button>';
99    html += '</td>';
100    html += '<td>';
101    html += '<button id="nextTrack" type="button" style="background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_nextTrack('+device+');">Next</button>';
102    html += '</td>';
103    html += '<td>';
104    html += '<button id="mute" type="button" style="background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_mute('+device+');">Mute</button>';
105    html += '</td>';
106    // html += '<td>';
107    // html += '<button type="button" style="background-color:lightgrey; height: 25px; width: 25px" onclick="Sonos_volumeDown('+device+');">-</button>';
108    // html += '</td>';
109    // html += '<td>';
110    // for (i=0; i<=10; i++) {
111        // var volume = i * 10;
112        // html += '<button id="volume'+i+'" type="button" style="background-color:lightgrey; height: 25px; width: 10px" onclick="Sonos_setVolume('+device+','+volume+');"></button>';
113    // }
114    // html += '</td>';
115    // html += '<td>';
116    // html += '<button type="button" style="background-color:lightgrey; height: 25px; width: 25px" onclick="Sonos_volumeUp('+device+');">+</button>';
117    // html += '</td>';
118    html += '</tr>';
119    html += '</table>';
120    html += '</DIV>'
121    html += '<DIV>'
122    html += '<table>';
123    html += '<tr>';
124    html += '<td>Audio Input:</td>';
125    html += '<td>';
126    html += '<select id="audioInputs"/>';
127    html += '<button id="playAudioInput" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_playAudioInput('+device+');">Play</button>';
128    html += '</td>';
129    html += '</tr>';
130    html += '<tr>';
131    html += '<td>Sonos playlist:</td>';
132    html += '<td>';
133    html += '<select id="savedQueues"/>';
134    html += '<button id="playSQ" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_playSQ('+device+');">Play</button>';
135    // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_enqueueSQ('+device+');">Enqueue</button>';
136    // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_enqueuePlaySQ('+device+');">Enqueue & Play</button>';
137    // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_playNextSQ('+device+');">Play next</button>';
138    // html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px" onclick="Sonos_replaceQueueSQ('+device+');">Replace queue</button>';
139    html += '</td>';
140    html += '</tr>';
141    html += '<tr>';
142    html += '<td>Queue:</td>';
143    html += '<td>';
144    html += '<select id="queue"/>';
145    html += '<button id="playQueue" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_playQueue('+device+');">Play</button>';
146    html += '<button id="clearQueue" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_clearQueue('+device+');">Clear</button>';
147    html += '</td>';
148    html += '</tr>';
149    html += '<tr>';
150    html += '<td>Favorites radios:</td>';
151    html += '<td>';
152    html += '<select id="favRadios"/>';
153    html += '<button id="playFavRadio" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_playFavRadio('+device+');">Play</button>';
154    html += '</td>';
155    html += '</tr>';
156    html += '<tr>';
157    html += '<td>URI:</td>';
158    html += '<td>';
159    html += '<select id="protocol" style="margin-right: 5px">';
160    html += '<option selected></option>';
161    html += '<option>x-file-cifs</option>';
162    html += '<option>file</option>';
163    html += '<option>x-rincon</option>';
164    html += '<option>x-rincon-mp3radio</option>';
165    html += '<option>x-rincon-playlist</option>';
166    html += '<option>x-rincon-queue</option>';
167    html += '<option>x-rincon-stream</option>';
168    html += '<option>x-sonosapi-stream</option>';
169    html += '<option>x-sonosapi-radio</option>';
170    html += '<option value="AI">Audio input</option>';
171    html += '<option value="SQ">Sonos playlist</option>';
172    html += '<option value="FR">Favorite radio</option>';
173    html += '<option value="TR">TuneIn radio</option>';
174    html += '<option value="SR">Sirius radio</option>';
175    html += '<option value="GZ">Group zone</option>';
176    html += '</select>';
177    html += '<input id="uri" type="text" style="width: 287px"/>';
178    html += '<button id="playUri" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_playUri('+device+');">Play</button>';
179    html += '</td>';
180    html += '</tr>';
181    html += '<tr>';
182    html += '<td>Text To Speech:</td>';
183    html += '<td>';
184    html += '<input id="text" type="text" style="margin-right: 10px; width: 237px"/>';
185    html += '<select id="language1" style="margin-right: 5px;" onChange="Sonos_selectLang();">';
186    html += '<option value="en" selected>English</option>';
187    html += '<option value="fr">French</option>';
188    html += '<option value="es">Spanish</option>';
189    html += '<option value="it">Italian</option>';
190    html += '<option value="ru">Russian</option>';
191    html += '</select>';
192    html += '<input id="language" type="text" value="en" style="margin-right: 10px; width: 20px"/>';
193    html += 'volume:';
194    html += '<input id="volume" type="text" value="" style="margin-left: 5px; width: 20px"/>';
195    html += '<button id="say" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_say('+device+');">Say</button>';
196    html += '</td>';
197    html += '</tr>';
198    html += '</table>';
199    html += '</DIV>'
200
201    //html += '<p id="debug">';
202
203    set_panel_html(html);
204
205    Sonos_prevGroups = undefined;
206    Sonos_prevSavedQueues = undefined;
207    Sonos_prevQueue = undefined;
208    Sonos_prevFavRadios = undefined;
209    Sonos_prevCoordinator = undefined;
210    Sonos_prevOnlineState = undefined;
211    Sonos_prevCurrentAlbumArtUrl = undefined;
212    Sonos_prevTitle = undefined;
213    Sonos_prevAlbum = undefined;
214    Sonos_prevArtist = undefined;
215    Sonos_prevDetails = undefined;
216    Sonos_prevCurrentTrack = undefined;
217    Sonos_prevNbrTracks = undefined;
218    Sonos_prevPlaying = undefined;
219    Sonos_prevActions = undefined;
220    Sonos_prevTransportUri = undefined;
221    Sonos_prevCurrentService = undefined;
222    Sonos_prevCurrentRadio = undefined;
223    Sonos_prevMute = undefined;
224    Sonos_prevVolume = undefined;
225
226    Sonos_refreshPlayer(device);
227}
228
229function Sonos_showHelp(device)
230{
231    Sonos_initXMLParser();
232
233    var zone = get_device_state(device, DEVICE_PROPERTIES_SID, "ZoneName", 1);
234    var uuid = get_device_state(device, DEVICE_PROPERTIES_SID, "SonosID", 1);
235    var groups = get_device_state(device, ZONEGROUPTOPOLOGY_SID, "ZoneGroupState", 1);
236
237    var members;
238    if (groups != undefined && groups != "") {
239        var xmlgroups = Sonos_parseXml(groups);
240        if (typeof xmlgroups != 'undefined') {
241            members = xmlgroups.getElementsByTagName("ZoneGroupMember");
242        }
243    }
244
245    var html = '';
246
247    html += '<a href="http://code.mios.com/trac/mios_sonos-wireless-music-systems#">Wiki</a>'
248    html += '<BR>'
249    html += '<a href="http://forum.micasaverde.com/index.php/board,47.0.html">Support forum</a>'
250
251    html += '<table cellspacing="10">';
252    html += '<tr>';
253    html += '<td>Sonos zone:</td>';
254    html += '<td>' + zone + '</td>';
255    html += '</tr>';
256    html += '<tr>';
257    html += '<td>Sonos UUID:</td>';
258    html += '<td>' + uuid + '</td>';
259    html += '</tr>';
260    html += '</table>';
261
262    html += '<table border="1">';
263    html += '<tr align="center" bgcolor="LightBlue">';
264    html += '<th>Description</td>';
265    html += '<th>Standard URI</td>';
266    html += '<th>Alternative URI for PlayURI</td>';
267    html += '</tr>';
268
269    html += '<tr>';
270    html += '<td>Sonos queue</td>';
271    html += '<td>x-rincon-queue:' + uuid + '#0</td>';
272    html += '<td>Q:</td>';
273    html += '</tr>';
274
275    html += '<tr>';
276    html += '<td>Third item in Sonos queue</td>';
277    html += '<td>x-rincon-queue:' + uuid + '#0 *</td>';
278    html += '<td>Q:3</td>';
279    html += '</tr>';
280
281    if (typeof members != 'undefined') {
282        for (i=0; i<members.length; i++) {
283            var zoneUUID = Sonos_extractXmlAttribute(members[i], 'UUID');
284            var zoneName = Sonos_extractXmlAttribute(members[i], 'ZoneName');
285            if (zoneName != zone) {
286                html += '<tr>';
287                html += '<td>Group with master zone "' + zoneName + '"</td>';
288                html += '<td>x-rincon:' + zoneUUID + '</td>';
289                html += '<td>GZ:' + zoneName + '</td>';
290                html += '</tr>';
291            }
292        }
293    }
294
295    html += '<tr>';
296    html += '<td>Local audio input</td>';
297    html += '<td>x-rincon-stream:' + uuid + '</td>';
298    html += '<td>AI:</td>';
299    html += '</tr>';
300
301    if (typeof members != 'undefined') {
302        for (i=0; i<members.length; i++) {
303            var zoneUUID = Sonos_extractXmlAttribute(members[i], 'UUID');
304            var zoneName = Sonos_extractXmlAttribute(members[i], 'ZoneName');
305            html += '<tr>';
306            html += '<td>Audio input of zone "' + zoneName + '"</td>';
307            html += '<td>x-rincon-stream:' + zoneUUID + '</td>';
308            html += '<td>AI:' + zoneName + '</td>';
309            html += '</tr>';
310        }
311    }
312
313    html += '<tr>';
314    html += '<td>TuneIn radio with sid 50486</td>';
315    html += '<td>x-sonosapi-stream:s50486?sid=254&flags=32 **</td>';
316    html += '<td>TR:50486</td>';
317    html += '</tr>';
318
319    html += '<tr>';
320    html += '<td>Sirius radio with sid shade45</td>';
321    html += '<td>x-sonosapi-hls:r%3ashade45?sid=37&flags=288 **</td>';
322    html += '<td>SR:shade45</td>';
323    html += '</tr>';
324
325    var favRadios = get_device_state(device, CONTENT_DIRECTORY_SID, "FavoritesRadios", 1);
326    if (favRadios != undefined && favRadios != "") {
327        var xmlFavRadios = Sonos_parseXml(favRadios);
328        if (typeof xmlFavRadios != 'undefined') {
329            var items = xmlFavRadios.getElementsByTagName("item");
330            for (i=0; i<items.length; i++) {
331                var title = Sonos_extractXmlTag(items[i], 'dc:title');
332                if (typeof title != 'undefined') {
333                    html += '<tr>';
334                    html += '<td>Favorite radio "' + title + '"</td>';
335                    html += '<td></td>';
336                    html += '<td>FR:' + title + '</td>';
337                    html += '</tr>';
338                    break;
339                }
340            }
341        }
342    }
343
344    var savedQueues = get_device_state(device, CONTENT_DIRECTORY_SID, "SavedQueues", 1);
345    if (savedQueues != undefined && savedQueues != "") {
346        var xmlSavedQueues = Sonos_parseXml(savedQueues);
347        if (typeof xmlSavedQueues != 'undefined') {
348            var containers = xmlSavedQueues.getElementsByTagName("container");
349            for (i=0; i<containers.length; i++) {
350                var title = Sonos_extractXmlTag(containers[i], 'dc:title');
351                var value = Sonos_extractXmlTag(containers[i], 'res');
352                if (typeof title != 'undefined' && typeof value != 'undefined') {
353                    html += '<tr>';
354                    html += '<td>Sonos playlist "' + title + '"</td>';
355                    html += '<td>' + value + '</td>';
356                    html += '<td>SQ:' + title + '</td>';
357                    html += '</tr>';
358                }
359            }
360        }
361    }
362
363    html += '</table>';
364    html += '<p>* Seek action is then required to select the right item</p>'
365    html += '<p>** Meta data have to be provided in addition to the standard URI</p>'
366
367    var variables = [   [ AVTRANSPORT_SID, "AVTransportURI" ],
368                        [ AVTRANSPORT_SID, "AVTransportURIMetaData" ],
369                        [ AVTRANSPORT_SID, "CurrentTrackURI" ],
370                        [ AVTRANSPORT_SID, "CurrentTrackMetaData" ],
371                        [ SONOS_SID, 'SonosServicesKeys' ] ];
372    html += '<table border="1">';
373    html += '<tr align="center" bgcolor="LightBlue">';
374    html += '<th>Variable</td>';
375    html += '<th>Value</td>';
376    html += '</tr>';
377    for (i=0; i<variables.length; i++) {
378        var value = get_device_state(device, variables[i][0], variables[i][1], 1);
379        if (value == undefined) {
380            value = '';
381        }
382        html += '<tr>';
383        html += '<td>' + variables[i][1] + '</td>';
384        html += '<td>' + Sonos_escapeHtmlSpecialChars(value) + '</td>';
385        html += '</tr>';
386    }
387    html += '</table>';
388
389    html += '<BR>';
390
391    set_panel_html(html);
392}
393
394function Sonos_showGroup(device)
395{
396    Sonos_detectBrowser();
397
398    Sonos_initXMLParser();
399
400    var html = '';
401
402    var groupMembers = get_device_state(device, ZONEGROUPTOPOLOGY_SID, "ZonePlayerUUIDsInGroup", 1);
403    var groups = get_device_state(device, ZONEGROUPTOPOLOGY_SID, "ZoneGroupState", 1);
404    if (groups != undefined && groups != "") {
405        var xmlgroups = Sonos_parseXml(groups);
406        if (typeof xmlgroups != 'undefined') {
407            var members = xmlgroups.getElementsByTagName("ZoneGroupMember");
408            for (i=0; i<members.length; i++) {
409                var name = Sonos_extractXmlAttribute(members[i], 'ZoneName');
410                var uuid = Sonos_extractXmlAttribute(members[i], 'UUID');
411                html += '<input id="GroupMember' + i +'" type="checkbox"';
412                if (groupMembers.search(uuid) >= 0) {
413                    html += ' checked';
414                }
415                html += ' value="' + name + '">' + name + '<BR>';
416            }
417            html += '<BR>';
418            html += '<button type="button" style="background-color:lightgrey; height: 25px; width: 100px" onclick="Sonos_selectAllMembers('+device+','+members.length+');">Select All</button>';
419            html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 100px" onclick="Sonos_unselectAllMembers('+device+','+members.length+');">Unselect All</button>';
420            html += '<button type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 100px" onclick="Sonos_updateGroup('+device+','+members.length+');">Apply</button>';
421        }
422    }
423
424    //html += '<p id="debug">';
425
426    set_panel_html(html);
427}
428
429function Sonos_showSettings(device)
430{
431    if (typeof Sonos_timeoutVar2 != 'undefined') {
432        clearTimeout(Sonos_timeoutVar2);
433    }
434
435    Sonos_detectBrowser();
436
437    Sonos_initXMLParser();
438
439    var html = '';
440
441    html += '<table cellspacing="10">';
442    html += '<tr><td colspan=2><u>Current settings</u></td></tr>';
443    html += '<tr>';
444    html += '<td>Zone:</td>';
445    html += '<td id="zone"></td>';
446    html += '</tr>';
447    html += '<tr>';
448    html += '<td>Model:</td>';
449    html += '<td id="model"></td>';
450    html += '</tr>';
451    html += '<tr>';
452    html += '<td>IP:</td>';
453    html += '<td id="IP"></td>';
454    html += '</tr>';
455    html += '<tr>';
456    html += '<td>State:</td>';
457    html += '<td>';
458    html += '<label id="state"/>';
459    html += '<button id="checkState" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 75px" onclick="Sonos_checkState('+device+');">Check</button>';
460    html += '</td>';
461    html += '</tr>';
462    html += '<tr>';
463    html += '<td>UPnP Event proxy:</td>';
464    html += '<td id="proxy"></td>';
465    html += '</tr>';
466    html += '<tr><td colspan=2><u>New settings</u></td></tr>';
467    html += '<tr><td colspan=2>Push "discover" button, then select your Sonos in the list and finally push "Select" button.';
468    html += '<BR>If UPnP discovery is not working, fill in your Sonos IP and finally push "Select" button.</td></tr>';
469    html += '<tr>';
470    html += '<td>';
471    html += '<button id="discover" type="button" style="background-color:lightgrey; height: 25px; width: 90px" onclick="Sonos_startSonosDiscovery('+device+');">Discover</button>';
472    html += '</td>';
473    html += '<td>';
474    html += '<select id="discovery"/>';
475    html += '<button id="selectDiscovery" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 75px" onclick="Sonos_selectDiscovery('+device+');">Select</button>';
476    html += '</td>';
477    html += '</tr>';
478    html += '<tr>';
479    html += '<td>New IP:</td>';
480    html += '<td>';
481    html += '<input id="newIP" type="text" style="width: 100px"/>';
482    html += '<button id="selectIP" type="button" style="margin-left: 10px; background-color:lightgrey; height: 25px; width: 50px" onclick="Sonos_selectIP('+device+');">Select</button>';
483    html += '</td>';
484    html += '</tr>';
485    html += '</table>';
486
487    //html += '<p id="debug">';
488
489    set_panel_html(html);
490
491    Sonos_prevModelName = undefined;
492    Sonos_prevIp = undefined;
493    Sonos_prevZone = undefined;
494    Sonos_prevOnlineState2 = undefined;
495    Sonos_prevProxy = undefined;
496    Sonos_prevResultDiscovery = undefined;
497
498    Sonos_refreshDiscovery(device);
499}
500
501function Sonos_detectBrowser()
502{
503    var place = navigator.userAgent.toLowerCase().indexOf('msie');
504    if (place == -1) {
505        Sonos_browserIE = false;
506    }
507    else {
508        Sonos_browserIE = true;
509    }
510}
511
512function Sonos_initXMLParser()
513{
514    if (typeof Sonos_parseXml == 'undefined') {
515        if (typeof window.DOMParser != "undefined") {
516            Sonos_parseXml = function(xmlStr) {
517                return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
518            };
519        }
520        else if (typeof window.ActiveXObject != "undefined" && new window.ActiveXObject("Microsoft.XMLDOM")) {
521            Sonos_parseXml = function(xmlStr) {
522                var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
523                xmlDoc.async = "false";
524                xmlDoc.loadXML(xmlStr);
525                return xmlDoc;
526            };
527        }
528        else {
529            Sonos_parseXml = function(xmlStr) {
530                return undefined;
531            };
532        }
533    }
534}
535
536function Sonos_extractXmlTag(parent, tag)
537{
538    var value = undefined;
539    for (j=0; j<parent.childNodes.length; j++) {
540        if (parent.childNodes[j].tagName == tag) {
541            value = parent.childNodes[j].textContent;
542            break;
543        }
544    }
545    return value;
546}
547
548function Sonos_extractXmlAttribute(node, attribute)
549{
550    var value = node.getAttribute(attribute);
551    return value;
552}
553
554function Sonos_escapeHtmlSpecialChars(unsafe)
555{
556    return unsafe
557            .replace(/&/g, "&amp;")
558            .replace(/</g, "&lt;")
559            .replace(/>/g, "&gt;")
560            .replace(/"/g, "&quot;");
561}
562
563function Sonos_refreshPlayer(device)
564{
565    var uuid = get_device_state(device, DEVICE_PROPERTIES_SID, "SonosID", 1);
566
567    var groups = get_device_state(device, ZONEGROUPTOPOLOGY_SID, "ZoneGroupState", 1);
568    if (groups != undefined && groups != "" && Sonos_prevGroups != groups) {
569        var xmlgroups = Sonos_parseXml(groups);
570        if (typeof xmlgroups != 'undefined') {
571            var html = "";
572            var members = xmlgroups.getElementsByTagName("ZoneGroupMember");
573            for (i=0; i<members.length; i++) {
574                var name = Sonos_extractXmlAttribute(members[i], 'ZoneName');
575                if (typeof name != 'undefined') {
576                    var title = name;
577                    if (title.length > 60) {
578                        title = title.substr(0, 59) + '...';
579                    }
580                    html += '<option value="AI:' + name + '">' + title + '</option>';
581                }
582            }
583            $('audioInputs').innerHTML = html;
584            if (Sonos_browserIE) {
585                $('audioInputs').outerHTML=$('audioInputs').outerHTML.replace($('audioInputs').innerHTML+'</select>',html+'</select>');
586            }
587        }
588        Sonos_prevGroups = groups;
589    }
590
591    var savedQueues = get_device_state(device, CONTENT_DIRECTORY_SID, "SavedQueues", 1);
592    if (savedQueues != undefined && savedQueues != "" && savedQueues != Sonos_prevSavedQueues) {
593        var xmlSavedQueues = Sonos_parseXml(savedQueues);
594        if (typeof xmlSavedQueues != 'undefined') {
595            var html = "";
596            var containers = xmlSavedQueues.getElementsByTagName("container");
597            for (i=0; i<containers.length; i++) {
598                var title = Sonos_extractXmlTag(containers[i], 'dc:title');
599                var value = Sonos_extractXmlTag(containers[i], 'res');
600                if (typeof title != 'undefined' && typeof value != 'undefined') {
601                    if (title.length > 60) {
602                        title = title.substr(0, 59) + '...';
603                    }
604                    html += '<option value="' + value + '">' + title + '</option>';
605                }
606            }
607            $('savedQueues').innerHTML = html;
608            if (Sonos_browserIE) {
609                $('savedQueues').outerHTML=$('savedQueues').outerHTML.replace($('savedQueues').innerHTML+'</select>',html+'</select>');
610            }
611        }
612        Sonos_prevSavedQueues = savedQueues;
613    }
614
615    var queue = get_device_state(device, CONTENT_DIRECTORY_SID, "Queue", 1);
616    if (queue != undefined && queue != "" && queue != Sonos_prevQueue) {
617        var xmlQueue = Sonos_parseXml(queue);
618        if (typeof xmlQueue != 'undefined') {
619            var html = "";
620            var items = xmlQueue.getElementsByTagName("item");
621            for (i=0; i<items.length; i++) {
622                var title = Sonos_extractXmlTag(items[i], 'dc:title');
623                var artist = Sonos_extractXmlTag(items[i], 'dc:creator');
624                var value = Sonos_extractXmlTag(items[i], 'res');
625                if (typeof title != 'undefined' && typeof value != 'undefined') {
626                    var title2 = title;
627                    if (typeof artist != 'undefined') {
628                        title2 += ' (' + artist + ')';
629                    }
630                    if (title2.length > 50) {
631                        title2 = title2.substr(0, 49) + '...';
632                    }
633                    html += '<option value="' + value + '">' + title2 + '</option>';
634                }
635            }
636            $('queue').innerHTML = html;
637            if (Sonos_browserIE) {
638                $('queue').outerHTML=$('queue').outerHTML.replace($('queue').innerHTML+'</select>',html+'</select>');
639            }
640        }
641        Sonos_prevQueue = queue;
642    }
643
644    var favRadios = get_device_state(device, CONTENT_DIRECTORY_SID, "FavoritesRadios", 1);
645    if (favRadios != undefined && favRadios != "" && favRadios != Sonos_prevFavRadios) {
646        var xmlFavRadios = Sonos_parseXml(favRadios);
647        if (typeof xmlFavRadios != 'undefined') {
648            var html = "";
649            var items = xmlFavRadios.getElementsByTagName("item");
650            for (i=0; i<items.length; i++) {
651                var title = Sonos_extractXmlTag(items[i], 'dc:title');
652                if (typeof title != 'undefined') {
653                    var title2 = title;
654                    if (title2.length > 60) {
655                        title2 = title2.substr(0, 59) + '...';
656                    }
657                    html += '<option value="' + title + '">' + title2 + '</option>';
658                }
659            }
660            $('favRadios').innerHTML = html;
661            if (Sonos_browserIE) {
662                $('favRadios').outerHTML=$('favRadios').outerHTML.replace($('favRadios').innerHTML+'</select>',html+'</select>');
663            }
664        }
665        Sonos_prevFavRadios = favRadios;
666    }
667
668    var coordinator = get_device_state(device, SONOS_SID, "GroupCoordinator", 1);
669    if (coordinator == undefined) {
670        coordinator = uuid;
671    }
672    var onlineState = get_device_state(device, SONOS_SID, "SonosOnline", 1);
673    if (onlineState == undefined) {
674        onlineState = '1';
675    }
676    var currentAlbumArtUrl = get_device_state(device, AVTRANSPORT_SID, "CurrentAlbumArt", 1);
677    if (currentAlbumArtUrl == undefined) {
678        currentAlbumArtUrl = '';
679    }
680    var title = get_device_state(device, AVTRANSPORT_SID, "CurrentTitle", 1);
681    if (title == undefined) {
682        title = '';
683    }
684    var album = get_device_state(device, AVTRANSPORT_SID, "CurrentAlbum", 1);
685    if (album == undefined) {
686        album = '';
687    }
688    var artist = get_device_state(device, AVTRANSPORT_SID, "CurrentArtist", 1);
689    if (artist == undefined) {
690        artist = '';
691    }
692    var details = get_device_state(device, AVTRANSPORT_SID, "CurrentDetails", 1);
693    if (details == undefined) {
694        details = '';
695    }
696    var currentTrack = get_device_state(device, AVTRANSPORT_SID, "CurrentTrack", 1);
697    if (currentTrack == undefined || currentTrack == "") {
698        currentTrack = '1';
699    }
700    var nbrTracks = get_device_state(device, AVTRANSPORT_SID, "NumberOfTracks", 1);
701    if (nbrTracks == undefined || nbrTracks == "NOT_IMPLEMENTED") {
702        nbrTracks = '';
703    }
704    var playing = get_device_state(device, AVTRANSPORT_SID, "TransportState", 1);
705    if (playing == undefined) {
706        playing = '';
707    }
708    var actions = get_device_state(device, AVTRANSPORT_SID, "CurrentTransportActions", 1);
709    if (actions == undefined) {
710        actions = '';
711    }
712    actions = actions.toLowerCase();
713    var transportUri = get_device_state(device, AVTRANSPORT_SID, "AVTransportURI", 1);
714    if (transportUri == undefined) {
715        transportUri = '';
716    }
717    var currentService = get_device_state(device, SONOS_SID, "CurrentService", 1);
718    if (currentService == undefined) {
719        currentService = '';
720    }
721    var currentRadio = get_device_state(device, AVTRANSPORT_SID, "CurrentRadio", 1);
722    if (currentRadio == undefined) {
723        currentRadio = '';
724    }
725    var mute = get_device_state(device, RENDERING_CONTROL_SID, "Mute", 1);
726    if (mute == undefined || mute == "") {
727        mute = '0';
728    }
729    var volume = get_device_state(device, RENDERING_CONTROL_SID, "Volume", 1);
730    if (volume == undefined || volume == "") {
731        volume = 0;
732    }
733
734    if (coordinator != Sonos_prevCoordinator
735        || onlineState != Sonos_prevOnlineState
736        || currentAlbumArtUrl != Sonos_prevCurrentAlbumArtUrl
737        || title != Sonos_prevTitle
738        || album != Sonos_prevAlbum
739        || artist != Sonos_prevArtist
740        || details != Sonos_prevDetails
741        || currentTrack != Sonos_prevCurrentTrack
742        || nbrTracks != Sonos_prevNbrTracks
743        || playing != Sonos_prevPlaying
744        || actions != Sonos_prevActions
745        || transportUri != Sonos_prevTransportUri
746        || currentService != Sonos_prevCurrentService
747        || currentRadio != Sonos_prevCurrentRadio
748        || mute != Sonos_prevMute
749        || volume != Sonos_prevVolume) {
750
751        $('albumArt').src = currentAlbumArtUrl;
752
753        var label;
754
755        if (title.indexOf('x-sonosapi', 0) == 0) {
756            title = '';
757        }
758        if (title != '') {
759            label = 'Track title:';
760        }
761        else {
762            label = '';
763        }
764        $('titleLabel').innerHTML = label;
765        $('title').innerHTML = title;
766
767        if (album != '') {
768            label = 'Album:';
769        }
770        else {
771            label = '';
772        }
773        $('albumLabel').innerHTML = label;
774        $('album').innerHTML = album;
775
776        if (artist != '') {
777            label = 'Artist:';
778        }
779        else {
780            label = '';
781        }
782        $('artistLabel').innerHTML = label;
783        $('artist').innerHTML = artist;
784
785        if (details != '') {
786            label = 'Information:';
787        }
788        else {
789            label = '';
790        }
791        $('detailsLabel').innerHTML = label;
792        $('details').innerHTML = details;
793
794        if (onlineState != '1' || coordinator != uuid || transportUri == '') {
795            if (onlineState != '1') {
796                $('trackLabel').innerHTML = 'Offline';
797            }
798            else if (coordinator != uuid) {
799                $('trackLabel').innerHTML = 'Group driven by another zone';
800            }
801            else {
802                $('trackLabel').innerHTML = 'No music';
803            }
804            $('track').innerHTML = '';
805            $('service').innerHTML = '';
806            $('radio').innerHTML = '';
807            $('play').style.backgroundColor = 'lightgrey';
808            $('pause').style.backgroundColor = 'lightgrey';
809            $('stop').style.backgroundColor = 'lightgrey';
810            if (onlineState != '1' || transportUri == '') {
811                $('play').disabled = true;
812                $('pause').disabled = true;
813                $('stop').disabled = true;
814                $('prevTrack').disabled = true;
815                $('nextTrack').disabled = true;
816            }
817            else {
818                $('play').disabled = false;
819                $('pause').disabled = false;
820                $('stop').disabled = false;
821                $('prevTrack').disabled = false;
822                $('nextTrack').disabled = false;
823            }
824        }
825        else {
826            if (nbrTracks == '' || nbrTracks == '0') {
827                $('trackLabel').innerHTML = '';
828                $('track').innerHTML = '';
829                $('prevTrack').disabled = true;
830                $('nextTrack').disabled = true;
831            }
832            else {
833                $('trackLabel').innerHTML = 'Track:';
834                $('track').innerHTML = currentTrack + '/' + nbrTracks;
835                if (currentTrack == "1") {
836                    $('prevTrack').disabled = true;
837                }
838                else {
839                    $('prevTrack').disabled = false;
840                }
841                if (nbrTracks == currentTrack) {
842                    $('nextTrack').disabled = true;
843                }
844                else {
845                    $('nextTrack').disabled = false;
846                }
847            }
848
849            if (playing == 'PLAYING' || playing == 'TRANSITIONING') {
850                $('play').style.backgroundColor = 'darkgray';
851                $('pause').style.backgroundColor = 'lightgrey';
852                $('stop').style.backgroundColor = 'lightgrey';
853            }
854            else if (playing == 'PAUSED_PLAYBACK') {
855                $('play').style.backgroundColor = 'lightgrey';
856                $('pause').style.backgroundColor = 'darkgray';
857                $('stop').style.backgroundColor = 'lightgrey';
858            }
859            else if (playing == 'STOPPED') {
860                $('play').style.backgroundColor = 'lightgrey';
861                $('pause').style.backgroundColor = 'lightgrey';
862                $('stop').style.backgroundColor = 'darkgray';
863            }
864            else {
865                $('play').style.backgroundColor = 'lightgrey';
866                $('pause').style.backgroundColor = 'lightgrey';
867                $('stop').style.backgroundColor = 'lightgrey';
868            }
869
870            if (actions.indexOf('play', 0) >= 0) {
871                $('play').disabled = false;
872            }
873            else {
874                $('play').disabled = true;
875            }
876            if (actions.indexOf('pause', 0) >= 0) {
877                $('pause').disabled = false;
878            }
879            else {
880                $('pause').disabled = true;
881            }
882            if (actions.indexOf('stop', 0) >= 0) {
883                $('stop').disabled = false;
884            }
885            else {
886                $('stop').disabled = true;
887            }
888            if (actions.indexOf('previous', 0) < 0) {
889                $('prevTrack').disabled = true;
890            }
891            if (actions.indexOf('next', 0) < 0) {
892                $('nextTrack').disabled = true;
893            }
894
895            if (transportUri.indexOf('x-rincon-stream:', 0) == 0
896                    || transportUri.indexOf('x-rincon-mp3radio:', 0) == 0
897                    || transportUri.indexOf('x-sonosapi-stream:', 0) == 0
898                    || transportUri.indexOf('x-sonosapi-radio:', 0) == 0
899                    || transportUri.indexOf('pndrradio:', 0) == 0) {
900                if ((transportUri.indexOf('x-rincon-mp3radio:', 0) == 0
901                            || transportUri.indexOf('x-sonosapi-stream:', 0) == 0)
902                        && title != '') {
903                    $('titleLabel').innerHTML = 'Stream:';
904                }
905                else if (transportUri.indexOf('x-rincon-stream:', 0) == 0 && title != '') {
906                    $('titleLabel').innerHTML = 'Source:';
907                }
908                $('trackLabel').innerHTML = '';
909                $('track').innerHTML = '';
910                if (transportUri.indexOf('x-rincon-stream:', 0) != 0) {
911                    $('pause').disabled = true;
912                }
913                if (transportUri.indexOf('x-sonosapi-radio:', 0) != 0
914                        && transportUri.indexOf('pndrradio:', 0) != 0) {
915                    $('prevTrack').disabled = true;
916                    $('nextTrack').disabled = true;
917                }
918                if (currentService == '' && transportUri.indexOf('x-rincon-mp3radio:', 0) == 0 && currentRadio != '') {
919                    currentService = 'Web radio:';
920                }
921            }
922            $('service').innerHTML = currentService;
923            $('radio').innerHTML = currentRadio;
924        }
925
926        if (mute == '1') {
927            $('mute').style.backgroundColor = 'darkgray';
928        }
929        else {
930            $('mute').style.backgroundColor = 'lightgrey';
931        }
932
933        if (onlineState == '1') {
934            $('mute').disabled = false;
935            $('playUri').disabled = false;
936            $('say').disabled = false;
937            $('playAudioInput').disabled = false;
938            $('playSQ').disabled = false;
939            $('playFavRadio').disabled = false;
940            if (coordinator != uuid) {
941                $('playQueue').disabled = true;
942                $('clearQueue').disabled = true;
943            }
944            else {
945                $('playQueue').disabled = false;
946                $('clearQueue').disabled = false;
947            }
948        }
949        else {
950            $('mute').disabled = true;
951            $('playUri').disabled = true;
952            $('say').disabled = true;
953            $('playAudioInput').disabled = true;
954            $('playSQ').disabled = true;
955            $('playFavRadio').disabled = true;
956            $('playQueue').disabled = true;
957            $('clearQueue').disabled = true;
958        }
959
960        // for (i=0; i<=10; i++) {
961            // var max = i * 10;
962            // var color = 'lightgrey';
963            // if (volume > 0 && volume >= max) {
964                // color = 'green';
965            // }
966            // $('volume'+i).style.backgroundColor = color;
967        // }
968
969        Sonos_prevCoordinator = coordinator;
970        Sonos_prevOnlineState = onlineState;
971        Sonos_prevCurrentAlbumArtUrl = currentAlbumArtUrl;
972        Sonos_prevTitle = title;
973        Sonos_prevAlbum = album;
974        Sonos_prevArtist = artist;
975        Sonos_prevDetails = details;
976        Sonos_prevCurrentTrack = currentTrack;
977        Sonos_prevNbrTracks = nbrTracks;
978        Sonos_prevPlaying = playing;
979        Sonos_prevActions = actions;
980        Sonos_prevTransportUri = transportUri;
981        Sonos_prevCurrentService = currentService;
982        Sonos_prevCurrentRadio = currentRadio;
983        Sonos_prevMute = mute;
984        Sonos_prevVolume = volume;
985    }
986
987    Sonos_timeoutVar = setTimeout("Sonos_refreshPlayer("+device+")", 1000);
988}
989
990function Sonos_refreshDiscovery(device)
991{
992    var modelName = get_device_state(device, SONOS_SID, "SonosModelName", 1);
993    if (modelName == undefined) {
994        modelName = '';
995    }
996    var ip = '';
997    for (i=0; i<jsonp.ud.devices.length; i++) {
998        if (jsonp.ud.devices[i].id == device) {
999            ip = jsonp.ud.devices[i].ip;
1000            break;
1001        }
1002    }
1003    var zone = get_device_state(device, DEVICE_PROPERTIES_SID, "ZoneName", 1);
1004    if (zone == undefined) {
1005        zone = '';
1006    }
1007    var onlineState = get_device_state(device, SONOS_SID, "SonosOnline", 1);
1008    if (onlineState == '1') {
1009        onlineState = 'ON';
1010    }
1011    else {
1012        onlineState = 'OFF';
1013    }
1014    var proxy = get_device_state(device, SONOS_SID, "ProxyUsed", 1);
1015    if (proxy == undefined) {
1016        proxy = '';
1017    }
1018    var resultDiscovery = get_device_state(device, SONOS_SID, "DiscoveryResult", 1);
1019    if (resultDiscovery == undefined) {
1020        resultDiscovery = '';
1021    }
1022
1023    if (modelName != Sonos_prevModelName
1024        || ip != Sonos_prevIp
1025        || zone != Sonos_prevZone
1026        || onlineState != Sonos_prevOnlineState2
1027        || proxy != Sonos_prevProxy
1028        || resultDiscovery != Sonos_prevResultDiscovery) {
1029
1030        Sonos_prevModelName = modelName;
1031        Sonos_prevIp = ip;
1032        Sonos_prevZone = zone;
1033        Sonos_prevOnlineState2 = onlineState;
1034        Sonos_prevProxy = proxy;
1035        Sonos_prevResultDiscovery = resultDiscovery;
1036
1037        $('model').innerHTML = modelName;
1038        $('IP').innerHTML = ip;
1039        $('zone').innerHTML = zone;
1040        $('state').innerHTML = onlineState;
1041        $('proxy').innerHTML = proxy;
1042
1043        if (resultDiscovery == 'scanning') {
1044            $('discover').disabled = true;
1045            $('discover').innerHTML = 'Scanning ...';
1046            $('discovery').innerHTML = '';
1047            $('selectDiscovery').disabled = true;
1048        }
1049        else if (resultDiscovery == "") {
1050            $('discover').disabled = false;
1051            $('discover').innerHTML = 'Discover';
1052            $('selectDiscovery').disabled = true;
1053            $('discovery').innerHTML = '';
1054        }
1055        else {
1056            $('discover').disabled = false;
1057            $('discover').innerHTML = 'Discover';
1058            $('selectDiscovery').disabled = false;
1059
1060            var html = '';
1061            var xml = Sonos_parseXml(resultDiscovery);
1062            if (typeof xml != 'undefined') {
1063                var items = xml.getElementsByTagName("device");
1064                for (i=0; i<items.length; i++) {
1065                    var url = Sonos_extractXmlTag(items[i], 'descriptionURL');
1066                    if (url == undefined) {
1067                        url = '';
1068                    }
1069                    var name = Sonos_extractXmlTag(items[i], 'friendlyName');
1070                    if (name == undefined) {
1071                        name = '';
1072                    }
1073                    var adrIP = Sonos_extractXmlTag(items[i], 'ip');
1074                    if (adrIP == undefined) {
1075                        adrIP = '';
1076                    }
1077                    var selected = '';
1078                    if (adrIP == ip) {
1079                        selected = ' selected';
1080                    }
1081                    var room = Sonos_extractXmlTag(items[i], 'roomName');
1082                    if (room == undefined) {
1083                        room = '';
1084                    }
1085                    html += '<option ' + selected + ' value="' + url + '">' + room + ' (' + name + ')</option>';
1086                }
1087            }
1088            $('discovery').innerHTML = html;
1089            if (Sonos_browserIE) {
1090                $('discovery').outerHTML=$('discovery').outerHTML.replace($('discovery').innerHTML+'</select>',html+'</select>');
1091            }
1092        }
1093    }
1094
1095    Sonos_timeoutVar2 = setTimeout("Sonos_refreshDiscovery("+device+")", 1000);
1096}
1097
1098function Sonos_play(device)
1099{
1100    Sonos_callAction(device, MEDIA_NAVIGATION_SID, 'Play', {} );
1101}
1102
1103function Sonos_pause(device)
1104{
1105    Sonos_callAction(device, MEDIA_NAVIGATION_SID, 'Pause', {} );
1106}
1107
1108function Sonos_stop(device)
1109{
1110    Sonos_callAction(device, MEDIA_NAVIGATION_SID, 'Stop', {} );
1111}
1112
1113function Sonos_prevTrack(device)
1114{
1115    Sonos_callAction(device, MEDIA_NAVIGATION_SID, 'SkipUp', {} );
1116}
1117
1118function Sonos_nextTrack(device)
1119{
1120    Sonos_callAction(device, MEDIA_NAVIGATION_SID, 'SkipDown', {} );
1121}
1122
1123function Sonos_mute(device)
1124{
1125    Sonos_callAction(device, RENDERING_CONTROL_SID, 'SetMute', {} );
1126}
1127
1128// function Sonos_setVolume(device, volume)
1129// {
1130    // Sonos_callAction(device, RENDERING_CONTROL_SID, 'SetVolume', {'DesiredVolume':volume} );
1131// }
1132
1133// function Sonos_volumeDown(device)
1134// {
1135    // Sonos_callAction(device, VOLUME_SID, 'Down', {} );
1136// }
1137
1138// function Sonos_volumeUp(device)
1139// {
1140    // Sonos_callAction(device, VOLUME_SID, 'Up', {} );
1141// }
1142
1143function Sonos_playAudioInput(device)
1144{
1145    if ($('audioInputs').selectedIndex >= 0) {
1146        var uri = $('audioInputs').options[$('audioInputs').selectedIndex].value;
1147        //$('debug').innerHTML = uri;
1148        Sonos_callAction(device, SONOS_SID, 'PlayURI', {'URIToPlay':uri} );
1149    }
1150}
1151
1152function Sonos_playSQ(device)
1153{
1154    if ($('savedQueues').selectedIndex >= 0) {
1155        var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;
1156        //$('debug').innerHTML = uri;
1157        Sonos_callAction(device, SONOS_SID, 'PlayURI', {'URIToPlay':uri} );
1158    }
1159}
1160
1161// function Sonos_enqueueSQ(device)
1162// {
1163    // if ($('savedQueues').selectedIndex >= 0) {
1164        // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;
1165        // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'ENQUEUE'} );
1166    // }
1167// }
1168
1169// function Sonos_enqueuePlaySQ(device)
1170// {
1171    // if ($('savedQueues').selectedIndex >= 0) {
1172        // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;
1173        // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'ENQUEUE_AND_PLAY'} );
1174    // }
1175// }
1176
1177// function Sonos_playNextSQ(device)
1178// {
1179    // if ($('savedQueues').selectedIndex >= 0) {
1180        // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;
1181        // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'ENQUEUE_AT_NEXT_PLAY'} );
1182    // }
1183// }
1184
1185// function Sonos_replaceQueueSQ(device)
1186// {
1187    // if ($('savedQueues').selectedIndex >= 0) {
1188        // var uri = $('savedQueues').options[$('savedQueues').selectedIndex].value;
1189        // Sonos_callAction(device, SONOS_SID, 'EnqueueURI', {'URIToEnqueue':uri, 'EnqueueMode':'REPLACE_QUEUE_AND_PLAY'} );
1190    // }
1191// }
1192
1193function Sonos_clearQueue(device)
1194{
1195    Sonos_callAction(device, AVTRANSPORT_SID, 'RemoveAllTracksFromQueue', {'InstanceID':'0'} );
1196}
1197
1198function Sonos_playQueue(device)
1199{
1200    var uri = 'Q:';
1201    var idx = $('queue').selectedIndex;
1202    if (idx >= 0) {
1203        idx += 1;
1204        uri += idx;
1205    }
1206    //$('debug').innerHTML = uri;
1207    Sonos_callAction(device, SONOS_SID, 'PlayURI', {'URIToPlay':uri} );
1208}
1209
1210function Sonos_playFavRadio(device)
1211{
1212    if ($('favRadios').selectedIndex >= 0) {
1213        var uri = 'FR:' + $('favRadios').options[$('favRadios').selectedIndex].value;
1214        //$('debug').innerHTML = uri;
1215        Sonos_callAction(device, SONOS_SID, 'PlayURI', {'URIToPlay':uri} );
1216    }
1217}
1218
1219function Sonos_playUri(device)
1220{
1221    var uri = encodeURIComponent($('uri').value);
1222    var protocol = $('protocol').value;
1223    if (protocol != "") {
1224        uri = protocol+':'+uri;
1225    }
1226    //$('debug').innerHTML = uri;
1227    if (uri != "") {
1228        Sonos_callAction(device, SONOS_SID, 'PlayURI', {'URIToPlay':uri} );
1229    }
1230}
1231
1232function Sonos_selectLang()
1233{
1234    if ($('language1').selectedIndex >= 0) {
1235        $('language').value = $('language1').options[$('language1').selectedIndex].value;
1236    }
1237}
1238
1239function Sonos_say(device)
1240{
1241    var text = $('text').value;
1242    var lang = $('language').value;
1243    var vol = $('volume').value;
1244    //$('debug').innerHTML = text + ' ' + lang + ' ' + vol;
1245    if (text != "") {
1246        Sonos_callAction(device, SONOS_SID, 'Say', {'Text':text, 'Language':lang, 'Volume':vol} );
1247    }
1248}
1249
1250function Sonos_selectAllMembers(device, nb)
1251{
1252    for (i=0; i<nb; i++) {
1253        $('GroupMember'+i).checked = true;
1254    }
1255}
1256
1257function Sonos_unselectAllMembers(device, nb)
1258{
1259    for (i=0; i<nb; i++) {
1260        $('GroupMember'+i).checked = false;
1261    }
1262}
1263
1264function Sonos_updateGroup(device, nb)
1265{
1266    var zones = "";
1267    for (i=0; i<nb; i++) {
1268        if ($('GroupMember'+i).checked) {
1269            if (zones != "") {
1270                zones += ',';
1271            }
1272            zones += $('GroupMember'+i).value;
1273        }
1274    }
1275    //$('debug').innerHTML = zones;
1276    Sonos_callAction(device, SONOS_SID, 'UpdateGroupMembers', {'Zones':zones} );
1277}
1278
1279function Sonos_startSonosDiscovery(device)
1280{
1281    Sonos_callAction(device, SONOS_SID, 'StartSonosDiscovery', {} );
1282}
1283
1284function Sonos_selectDiscovery(device)
1285{
1286    if ($('discovery').selectedIndex >= 0) {
1287        var url = $('discovery').options[$('discovery').selectedIndex].value;
1288        //$('debug').innerHTML = url;
1289        Sonos_callAction(device, SONOS_SID, 'SelectSonosDevice', {'URL':url} );
1290    }
1291}
1292
1293function Sonos_selectIP(device)
1294{
1295    if ($('newIP').value != "") {
1296        var url = 'http://' + $('newIP').value + ':1400/xml/device_description.xml';
1297        //$('debug').innerHTML = url;
1298        Sonos_callAction(device, SONOS_SID, 'SelectSonosDevice', {'URL':url} );
1299    }
1300}
1301
1302function Sonos_checkState(device)
1303{
1304    if ($('IP').innerHTML != "") {
1305        var url = 'http://' + $('IP').innerHTML + ':1400/xml/device_description.xml';
1306        //$('debug').innerHTML = url;
1307        Sonos_callAction(device, SONOS_SID, 'SelectSonosDevice', {'URL':url} );
1308    }
1309}
1310
1311function Sonos_callAction(device, sid, actname, args) {
1312    var q={
1313        'id':'lu_action',
1314        'output_format':'xml',
1315        'DeviceNum':device,
1316        'serviceId':sid,
1317        'action':actname
1318    };
1319    var key, count = 0;
1320    for(key in args) {
1321        count++;
1322    }
1323    if (count > 0) {
1324        Object.extend(q, args);
1325    }
1326    if (Sonos_browserIE) {
1327        Object.extend(q, {timestamp: new Date().getTime()}); //we need this to avoid IE caching of the AJAX get
1328    }
1329    new Ajax.Request (command_url+'/data_request', {
1330        method: 'get',
1331        parameters: q,
1332        onSuccess: function (response) {
1333        },
1334        onFailure: function (response) {
1335        },
1336        onComplete: function (response) {
1337        }
1338    });
1339}
1340
Note: See TracBrowser for help on using the repository browser.