1.. _examples: 2 3Examples 4======== 5 6This page contains collection of small examples to show of the features of 7*SoCo* and hopefully get you well started with the library. 8 9All examples are shown as if entered in the Python interpreter (as apposed to 10executed from a file) because that makes it easy to incorporate output in the 11code listings. 12 13All the examples from :ref:`examples_playback_control` and forward 14assume that you have followed one of the examples in 15:ref:`examples_getting_your_devices` and therefore already have a 16variable named ``device`` that points to a :class:`soco.SoCo` 17instance. 18 19.. _examples_getting_your_devices: 20 21Getting your devices 22-------------------- 23 24Getting all your devices 25^^^^^^^^^^^^^^^^^^^^^^^^ 26 27To get all your devices use the :func:`soco.discover` function:: 28 29 >>> import soco 30 >>> devices = soco.discover() 31 >>> devices 32 set([SoCo("192.168.0.10"), SoCo("192.168.0.30"), SoCo("192.168.0.17")]) 33 >>> device = devices.pop() 34 >>> device 35 SoCo("192.168.0.16") 36 37Getting any device 38^^^^^^^^^^^^^^^^^^ 39 40To get any device use the :func:`soco.discovery.any_soco` function. This can be 41useful for cases where you really do not care which one you get, you just need 42one e.g. to query for music library information:: 43 44 >>> import soco 45 >>> device = soco.discovery.any_soco() 46 >>> device 47 SoCo("192.168.0.16") 48 49Getting a named device 50^^^^^^^^^^^^^^^^^^^^^^ 51 52Getting a device by player name can be done with the 53:func:`soco.discovery.by_name` function:: 54 55 >>> from soco.discovery import by_name 56 >>> device = by_name("Living Room") 57 >>> device 58 SoCo("192.168.1.18") 59 60 61.. _examples_handle_group: 62 63Handling groups of devices 64-------------------------- 65 66Information about a group 67^^^^^^^^^^^^^^^^^^^^^^^^^ 68 69To get information about a group, pick a device and use the :attr:`~soco.core.SoCo.all_groups` 70property:: 71 72 >>> import soco 73 >>> devices = {device.player_name: device for device in soco.discover()} 74 >>> devices 75 {'Living Room': SoCo("192.168.1.47"), 'Office': SoCo("192.168.1.48")} 76 77 >>> devices['Living Room'].all_groups 78 {ZoneGroup(uid='RINCON_347E5C68F04001400:2900176654', coordinator=SoCo("192.168.1.48"), members={SoCo("192.168.1.48")}), 79 ZoneGroup(uid='RINCON_7828CAF58E6E01400:3613865501', coordinator=SoCo("192.168.1.47"), members={SoCo("192.168.1.47")})} 80 81In the case above, there are two independent devices, one group for each device with the device as its only member. 82 83Join/unjoin devices 84^^^^^^^^^^^^^^^^^^^ 85 86You can use the :meth:`~soco.core.SoCo.join` method to join a device to another 'master' device:: 87 88 >>> devices['Office'].join(devices['Living Room']) 89 >>> devices['Living Room'].all_groups 90 {ZoneGroup(uid='RINCON_7828CAF58E6E01400:3613865501', coordinator=SoCo("192.168.1.47"), members={SoCo("192.168.1.47"), SoCo("192.168.1.48")})} 91 92Now, there is a single group composed of the two devices, with the Living Room device as the coordinator of the group. 93 94Use the :meth:`~soco.core.SoCo.unjoin` method to unjoin a device in a group:: 95 96 >>> devices['Living Room'].unjoin() 97 >>> devices['Living Room'].all_groups 98 {ZoneGroup(uid='RINCON_7828CAF58E6E01400:3613865501', coordinator=SoCo("192.168.1.48"), members={SoCo("192.168.1.48")}), 99 ZoneGroup(uid='RINCON_7828CAF58E6E01400:3613865502', coordinator=SoCo("192.168.1.47"), members={SoCo("192.168.1.47")})} 100 101Party mode 102^^^^^^^^^^ 103 104Use the :meth:`~soco.core.SoCo.partymode` method to join all the devices in your network into a single group, in one command:: 105 106 >>> devices['Living Room'].partymode() 107 >>> devices['Living Room'].all_groups 108 {ZoneGroup(uid='RINCON_7828CAF58E6E01400:3613865501', coordinator=SoCo("192.168.1.47"), members={SoCo("192.168.1.47"), SoCo("192.168.1.48")})} 109 110 111.. _examples_playback_control: 112 113Playback control 114---------------- 115 116Play, pause and stop 117^^^^^^^^^^^^^^^^^^^^ 118 119The normal play, pause and stop functionality is provided with 120similarly named methods (:meth:`~soco.core.SoCo.play`, 121:meth:`~soco.core.SoCo.pause` and :meth:`~soco.core.SoCo.stop`) on the 122:class:`~soco.core.SoCo` instance and the current state is included in the 123output of :meth:`~soco.core.SoCo.get_current_transport_info`:: 124 125 >>> device.get_current_transport_info()['current_transport_state'] 126 'STOPPED' 127 >>> device.play() 128 >>> device.get_current_transport_info()['current_transport_state'] 129 'PLAYING' 130 >>> device.pause() 131 >>> device.get_current_transport_info()['current_transport_state'] 132 'PAUSED_PLAYBACK' 133 134More playback control with next, previous and seek 135^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 136 137Navigating to the next or previous track is similarly done with 138methods of the same name (:meth:`~soco.core.SoCo.next` and 139:meth:`~soco.core.SoCo.previous`) and information about the current 140position in the queue is contained in the output from 141:meth:`~soco.core.SoCo.get_current_track_info`:: 142 143 >>> device.get_current_track_info()['playlist_position'] 144 '29' 145 >>> device.next() 146 >>> device.get_current_track_info()['playlist_position'] 147 '30' 148 >>> device.previous() 149 >>> device.get_current_track_info()['playlist_position'] 150 '29' 151 152Seeking is done with the :meth:`~soco.core.SoCo.seek` method. Note 153that the input for that method is a string on the form "HH:MM:SS" or 154"H:MM:SS". The current position is also contained in 155:meth:`~soco.core.SoCo.get_current_track_info`:: 156 157 >>> device.get_current_track_info()['position'] 158 '0:02:59' 159 >>> device.seek("0:00:30") 160 >>> device.get_current_track_info()['position'] 161 '0:00:31' 162 163Control of a group 164^^^^^^^^^^^^^^^^^^ 165 166Only the coordinator of a group can control playback (play, pause, stop, next, 167previous, seek commands) and manage the queue (add or remove track, clear the queue). 168A :class:`~soco.exceptions.SoCoSlaveException` exception will be raised if a 169master-only command is called on a non-coordinator device. 170 171Other commands like volume, loudness and treble, mute, night mode can be controlled on each 172individual player in the group. 173 174You can use the :attr:`~soco.core.SoCo.is_coordinator` property to see if a device is the 175coordinator:: 176 177 >>> devices['Living Room'].is_coordinator 178 True 179 180From a device, you can get the coordinator of a group by using the 181:attr:`~soco.core.SoCo.group` property of the :class:`~soco.core.SoCo` instance, 182which returns a :class:`~soco.groups.ZoneGroup` instance allowing access to its 183:attr:`~soco.groups.ZoneGroup.coordinator` property:: 184 185 >>> devices['Living Room'].group.coordinator 186 SoCo("192.168.1.47") 187 >>> devices['Office'].group.coordinator 188 SoCo("192.168.1.47") 189 190To set a group volume, use the :attr:`~soco.groups.ZoneGroup.volume` property or the 191:meth:`~soco.groups.ZoneGroup.set_relative_volume` method:: 192 193 >>> # let's define some aliases ... 194 >>> lr = devices['Living Room'] 195 >>> of = devices['Office'] 196 >>> lr.volume, of.volume 197 (17, 10) 198 >>> g = lr.group # alias to the group 199 >>> g.volume 200 13 201 >>> g.volume = 20 202 >>> lr.volume, of.volume 203 (27, 13) 204 205 206Seeing and manipulating the queue 207--------------------------------- 208 209Getting the queue 210^^^^^^^^^^^^^^^^^ 211 212Getting the queue is done with the :meth:`~soco.core.SoCo.get_queue` method:: 213 214 >>> queue = device.get_queue() 215 >>> queue 216 Queue(items=[<DidlMusicTrack 'b'Blackened'' at 0x7f2237006dd8>, ..., <DidlMusicTrack 'b'Dyers Eve'' at 0x7f2237006828>]) 217 218The returned :class:`~soco.data_structures.Queue` object is a sequence 219of items from the queue, meaning that it can be iterated over and its 220length aquired with :func:`len`:: 221 222 >>> len(queue) 223 9 224 >>> for item in queue: 225 ... print(item.title) 226 ... 227 Blackened 228 ...and Justice for All 229 Eye of the Beholder 230 One 231 The Shortest Straw 232 Harvester of Sorrow 233 The Frayed Ends of Sanity 234 To Live Is to Die 235 Dyers Eve 236 237The queue object also has :attr:`~.ListOfMusicInfoItems.total_matches` 238and :attr:`~.ListOfMusicInfoItems.number_returned` attributes, which 239are used to figure out whether paging is required in order to get all 240elements of the queue. See the :class:`~.ListOfMusicInfoItems` 241docstring for details. 242 243Clearing the queue 244^^^^^^^^^^^^^^^^^^ 245 246Clearing the queue is done with the 247:meth:`~soco.core.SoCo.clear_queue` method as follows:: 248 249 >>> queue = device.get_queue() 250 >>> len(queue) 251 9 252 >>> device.clear_queue() 253 >>> queue = device.get_queue() 254 >>> len(queue) 255 0 256 257Listing and deleting music library shares 258----------------------------------------- 259 260Music library shares are the local network drive shares connected to 261Sonos, which host the audio content in the Sonos Music Library. 262 263To list the shares connected to Sonos, use the 264:meth:`~soco.music_library.MusicLibrary.list_library_shares` method as follows:: 265 266 >>> device.music_library.list_library_shares() 267 ['//share_host_01/music', '//share_host_02/music'] 268 269The result is a list of network share locations. 270 271To delete a network share, use the 272:meth:`~soco.music_library.MusicLibrary.delete_library_share` method as follows:: 273 274 >>> device.music_library.delete_library_share('//share_host_01/music') 275 276You may want to check that the deletion has succeeded, by waiting a few seconds, 277then confirming that the share has disappeared from the list of shares. 278