bosesoundtouchapi.soundtouchclient

@export
class SoundTouchClient:

The SoundTouchClient uses the underlying Bose Web Socket api to communicate with a specified Bose SoundTouch device.

This client communicates with a Bose device on port 8090 by default (the standard WebAPI port), but the port number can be changed.

The client uses an urllib3.PoolManager instance to delegate the HTTP-requests. Set a custom manager with the manage_traffic() method.

Like the BoseWebSocket, this client can be used in two ways: 1. create a client manually or 2. use the client within a _with_ statement. Additionally, this class implements a dict-like functionality. So, the loaded configuration can be accessed by typing: config = client[<config_name>]

SoundTouchClient( device: bosesoundtouchapi.soundtouchdevice.SoundTouchDevice, raiseErrors: bool = True, manager: urllib3.poolmanager.PoolManager = None)

Initializes a new instance of the class.

Arguments:
  • device (SoundTouchDevice): The device to interace with. Some configuration data stored here will be updated if specific methods were called in this client.
  • raiseErrors (bool): Specifies if the client should raise exceptions returned by the SoundTouch device. Use ignore to ignore the errors (they will be given as the response object in a SoundTouchMessage). Default = 'raise'.
  • manager (urllib3.PoolManager): The manager for HTTP requests to the device.
ConfigurationCache: dict

A dictionary of cached configuration objects that have been obtained from the SoundTouch device. Use the objects in this cache whenever it is too expensive or time consuming to make a real-time request from the device.

The configuration cache is updated for any "Get...()" methods that return device information. All of the "Get...()" methods have a refresh:bool argument that controls where information is obtained from; if refresh=True, then the device is queried for real-time configuration information. If refresh=False, then the configuration information is pulled from the configuration cache dictionary; if the cache does not contain the object, then the device is queried for real-time configuration information.

It is obviously MUCH faster to retrieve device configuration objects from the cache than from real-time device queries. This works very well for configuration objects that do not change very often (e.g. Capabilities, Language, SourceList, etc). You will still want to make real-time queries for configuration objects that change frequently (e.g. Volume, NowPlayingStatus, Presets, etc).

This property is read-only, and is set when the class is instantiated. The dictionary entries can be changed, but not the dictionary itself.

Returns:

The _ConfigurationCache property value.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get cached configuration objects, refreshing from device if needed.
    # since the refresh argument is false to all of these, they will request
    # real-time information from the device the first time, and then the
    # ConfigurationCache will be updated with the results.
    sourceList:SourceList = client.GetSourceList(False)

    print("\nCached configuration:\n%s" % sourceList.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.sources.Path in client.ConfigurationCache:
        sourceList:SourceList = client.ConfigurationCache[SoundTouchNodes.sources.Path]
        print("\nCached configuration, direct:\n%s" % sourceList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

The SoundTouchDevice object used to connect to the SoundTouch device.

This property is read-only, and is set when the class is instantiated.

Manager: urllib3.poolmanager.PoolManager

Sets the request PoolManager object to use for http requests to the device.

Returns:

The `_Manager' property value.

SnapshotSettings: dict

A dictionary of configuration objects that are used by the Snapshot processing methods.

This property is read-only.

def Action( self, keyName: bosesoundtouchapi.soundtouchkeys.SoundTouchKeys, keyState: bosesoundtouchapi.models.keystates.KeyStates = <KeyStates.Both: 'both'>) -> None:

Tries to imitate a pressed key.

Arguments:
  • keyName (SoundTouchKeys|str): The specified key to press.
  • keyState (KeyStates|str): Key state to select (press, release, or both).

This method can be used to invoke different actions by using the different keys defined in bosesoundtouchapi.soundtouchkeys.SoundTouchKeys.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # send a PRESET_1 action to play a preset (only release state required).
    print("Sending PRESET_1 key release ...")
    client.Action(SoundTouchKeys.PRESET_1, KeyStates.Release)
    time.sleep(5)

    # send a PRESET_1 action to store a preset (only press state required).
    print("Sending PRESET_1 key press ...")
    client.Action(SoundTouchKeys.PRESET_1, KeyStates.Press)
    time.sleep(5)

    # send a VOLUME_UP action to adjust volume (both press and release states required).
    print("Sending VOLUME_UP key press and release ...")
    client.Action(SoundTouchKeys.VOLUME_UP, KeyStates.Both)
    time.sleep(5)

    # send a MUTE action to mute volume (only press state required).
    print("Sending MUTE key press ...")
    client.Action(SoundTouchKeys.MUTE, KeyStates.Press)
    time.sleep(5)

    # send a POWER action to toggle power state (both press and release states required).
    print("Sending POWER key press and release ...")
    client.Action(SoundTouchKeys.POWER, KeyStates.Both)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def AddFavorite(self) -> None:

Adds the currently playing media to the device favorites.

This will first make a call to GetNowPlayingStatus() method to ensure favorites are enabled for the now playing media. If not enabled, then the request is ignored and no exception is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # are favorite functions allowed for currently playing media?
    if nowPlaying.IsFavoriteEnabled:

        # add the currently playing media to the device favorites.
        client.AddFavorite()

        # give the device time to process the change.
        time.sleep(1)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    else:

        print("\nFavorites not enabled for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def AddMusicServiceSources(self) -> list[str]:

Adds any servers in the MediaServerList to the sources list if they do not exist in the sources list as a "STORED_MUSIC" source.

Returns:

A list of descriptions (e.g. "Friendly Name (sourceAccount)") that were added to the source list.

This method retrieves the list of available media servers, as well as the list of sources defined to the device. It will then compare the two lists, adding any media server(s) to the source list if they are not present.

UPnP media server music service (e.g. "STORED_MUSIC") sources can only be added if the device has detected the UPnP media server. The detected UPnP media servers will appear in the MediaServerList of items obtained using a call to GetMediaServerList method.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time 

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get list of defined sources.
    sourceList:SourceList = client.GetSourceList()
    print("\nSource list before the change:\n%s" % sourceList.ToString(True))

    # get list of upnp media services detected by the device.
    mediaServerList:MediaServerList = client.GetMediaServerList()
    print("\nUPnP Media Server list before the change:\n%s" % mediaServerList.ToString(True))

    # ensure all upnp media servers are defined as sources.
    print("\n\nVerifying UPnP media servers are defined as sources ...")
    sourcesAdded:list[str] = client.AddMusicServiceSources()
    if len(sourcesAdded) == 0:
        print(" *** All UPnP media servers are already defined as sources")
    else:
        print("Sources added:\n%s" % str(sourcesAdded))

        # get list of defined sources.
        sourceList:SourceList = client.GetSourceList()
        print("\nSource list after the change:\n%s" % sourceList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Adds a station to a music service (e.g. PANDORA, etc) collection of previously stored stations.

Arguments:
  • addStation (AddStation): Criteria used to add the music service station.
Returns:

A SoundTouchMessage object that contains the response.

Raises:
  • SoundTouchError: If the device is not capable of supporting addStation functions, as determined by a query to the cached supportedURLs web-services api.

The added station will be immediately selected for playing.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get my collection of PANDORA music service stations.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId", menuType=NavigateMenuTypes.RadioStations)
    resultsBefore:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\n%s Music Service Stations before:\n%s" % (criteria.Source, resultsBefore.ToString(True)))

    # add station to my collection of PANDORA music service stations.
    addStation:AddStation = AddStation(SoundTouchSources.PANDORA, "YourMusicServiceUserId", "R4328162", "Zach Williams & Essential Worship")
    print("\nAdding Station: %s" % addStation.ToString())
    client.AddMusicServiceStation(addStation)

    # get my collection of PANDORA music service stations.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId", menuType=NavigateMenuTypes.RadioStations)
    resultsAfter:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\n%s Music Service Stations after:\n%s" % (criteria.Source, resultsAfter.ToString(True)))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Adds the given zone members to the device's zone.

Arguments:
  • members (list): A list of ZoneMember objects to add to the master zone.
  • delay (int): Time delay (in seconds) to wait AFTER adding zone members. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.
Raises:
  • SoundTouchError: Master zone status could not be retrieved.
    Master zone does not exist; zone members cannot be added.
    Members argument was not supplied, or has no members.
    Members argument contained a list item that is not of type ZoneMember.

The SoundTouch master device cannot find zone members without their device id.

The SoundTouch device does not return errors if a zone member device id does not exist; it simply ignores the invalid member entry and moves on to the next.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # build list of zone members to add.
    zoneMembers:list = []
    zoneMembers.append(ZoneMember("192.168.1.80", "E8EB11B9B723"))
    zoneMembers.append(ZoneMember("192.168.1.82", "F9BC35A6D825"))
    zoneMembers.append(ZoneMember("192.168.1.83", "B8BD47C7F452"))

    # get current zone configuration status.
    zoneBefore:Zone = client.GetZoneStatus()
    print("\nCurrent Zone Status:\n%s" % zoneBefore.ToString(True))

    # if zone not active, then create one so that we have something to add.
    if len(zoneBefore.Members) == 0:

        print("Creating a new master zone so we have a master zone to add to ...")

        # initialize the new master zone configuration.
        masterZone:Zone = Zone(client.Device.DeviceId, client.Device.Host,True) # <- master
        member:ZoneMember
        for member in zoneMembers:
            masterZone.AddMember(member)                                        # <- member
            break   # only add 1 zone member, so it actually adds something below

        # create a new master zone configuration on the device.
        client.CreateZone(masterZone)

        # get current zone configuration status.
        zoneBefore:Zone = client.GetZoneStatus()
        print("\nZone Status Before:\n%s" % zoneBefore.ToString(True))

    # add zone members to the master zone configuration.
    client.AddZoneMembers(zoneMembers)

    # get current zone configuration status.
    zoneAfter:Zone = client.GetZoneStatus()
    print("\nZone Status After:\n%s" % zoneAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def ClearBluetoothPaired(self) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Clears all existing bluetooth pairings from the device.

Raises:
  • SoundTouchError: If the device is not capable of supporting enterBluetoothPairing function, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

After the method completes, any existing bluetooth pairings from other devices will no longer be able to connect; you will need to re-pair each device.

Some SoundTouch devices will emit a descending tone when the pairing list is cleared.

Sample Code

import time
from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # clear bluetooth pairing list.
    print("Clearing Bluetooth pairing list ...")
    client.ClearBluetoothPaired()

except Exception as ex:

    print("** Exception: %s" % str(ex))

def CreateGroupStereoPair( self, group: bosesoundtouchapi.models.group.Group) -> bosesoundtouchapi.models.group.Group:

Creates a new left / right stereo pair speaker group.

Arguments:
  • group (Group): Speaker group configuration object that defines the group.
Raises:
  • SoundTouchError: group argument was not supplied.
    group argument is not of type Group.
    group argument did not contain any roles. The group must have at least two group roles in order to create a group.

The device that issues the call to this method will be the master of the group.

The group argument should contain 2 roles (LEFT and RIGHT) with the device information (ip address and device id).

The device will generate a groupUpdated websocket event, which contains the updated Group configuration.

The ST-10 is the only SoundTouch product that supports stereo pair groups.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current group configuration status.
    groupBefore:Group = client.GetGroupStereoPairStatus()
    print("\nGroup Status Before:\n%s" % groupBefore.ToString(True))

    # initialize the new group configuration.
    group:Group = Group(name="Bose-ST10-1 + Bose-ST10-4", masterDeviceId="9070658C9D4A")
    group.AddRole(GroupRole("192.168.1.81", "9070658C9D4A", GroupRoleTypes.Left))
    group.AddRole(GroupRole("192.168.1.84", "F45EAB3115DA", GroupRoleTypes.Right))

    # create a new group configuration on the device.
    print("\nCreating Group: %s" % group.Name)
    groupAfter:Group = client.CreateGroupStereoPair(group)
    print("\nGroup Status After:\n%s" % groupAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Creates a multiroom zone from a Zone object.

Arguments:
  • zone (Zone): Multiroom configuration (zone) object that will control the zone (e.g. the master). This object also contains a list of all zone members that will be under its control (e.g. Members property).
  • delay (int): Time delay (in seconds) to wait AFTER creating the zone. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.
Raises:
  • SoundTouchError: Zone argument was not supplied.
    Zone argument is not of type Zone.
    Zone argument did not contain any members. The zone must have at least one zone member in order to create a zone.

The master SoundTouch device cannot find zone members without their device id.

The device that issues the call to this method will be the master of the zone. Multiple ZoneMember entries can be specified in the Zone object, to create a zone with ALL members in one call.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current zone configuration status.
    zoneBefore:Zone = client.GetZoneStatus()
    print("\nZone Status Before:\n%s" % zoneBefore.ToString(True))

    # initialize the new master zone configuration.
    masterZone:Zone = Zone(client.Device.DeviceId, client.Device.Host, True) # <- master
    masterZone.AddMember(ZoneMember("192.168.1.80", "E8EB11B9B723"))        # <- member

    # create a new master zone configuration on the device.
    client.CreateZone(masterZone)

    # get current zone configuration status.
    zoneAfter:Zone = client.GetZoneStatus()
    print("\nZone Status After:\n%s" % zoneAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def CreateZoneFromDevices( self, master: bosesoundtouchapi.soundtouchdevice.SoundTouchDevice, members: list) -> bosesoundtouchapi.models.zone.Zone:

Creates a new multiroom zone with the given member devices.

Arguments:
  • master (SoundTouchDevice): The device object that will control the zone (e.g. the master).
  • members (list): A list of SoundTouchDevice objects that will be controlled by the master zone (e.g. the zone members).
Raises:
  • SoundTouchError: Master argument was not supplied.
    Master argument is not of type SoundTouchDevice.
    Members argument is not of type list.
    Members argument was not supplied, or has no members.
    Members argument contained a list item that is not of type SoundTouchDevice.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current zone configuration status.
    zoneBefore:Zone = client.GetZoneStatus()
    print("\nZone Status Before:\n%s" % zoneBefore.ToString(True))

    # create new device instances for all zone members.
    device_master:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # master
    device_member:SoundTouchDevice = SoundTouchDevice("192.168.1.80") # member

    # create a new master zone configuration on the device.
    masterZone:Zone = client.CreateZoneFromDevices(device_master, [device_member])
    print("\nMaster Zone created:\n%s" % (masterZone.ToString(True)))

    # get current zone configuration status.
    zoneAfter:Zone = client.GetZoneStatus()
    print("\nZone Status After:\n%s" % zoneAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def EnterBluetoothPairing(self) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Enters bluetooth pairing mode, and waits for a compatible device to pair with.

Raises:
  • SoundTouchError: If the device is not capable of supporting enterBluetoothPairing function, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

On the device you want to connect (e.g. phone, tablet, etc), turn on Bluetooth. In the Bluetooth settings menu of the device, the SoundTouch device name should appear within a few seconds and allow your device to pair with it. Some SoundTouch devices will have a bluetooth indicator that turns blue when pairing mode is entered, as well as emit an asccending tone when the pairing is complete.

Once pairing is complete, the source is immediately switched to BLUETOOTH.

Sample Code

import time
from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # enter bluetooth pairing mode.
    print("\nEntering Bluetooth pairing mode - check your mobile device Bluetooth list ...")
    client.EnterBluetoothPairing()

except Exception as ex:

    print("** Exception: %s" % str(ex))

Makes a GET request to retrieve a stored value.

Use this method when querying for specific nodes. All standard nodes are implemented by this class.

Arguments:
  • uri (SoundTouchUri): The node where the requested value is stored. DANGER: This request can also have a massive effect on your Bose device, for instance when calling client.get(SoundTouchNodes.resetDefaults), it will wipe all data on the device and perform a factory reset.
Returns:

An object storing the request uri, optional a payload that has been sent and the response as an xml.etree.ElementTree.Element.

Raises:
  • SoundTouchError: When errors should not be ignored on this client, they will raise a SoundTouchError exception with all information related to that error.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.uri import *
from xml.etree.ElementTree import Element
from xml.etree import ElementTree

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get configuration for specified node.
    msg:SoundTouchMessage = client.Get(SoundTouchNodes.volume)

    if msg != None:
        ElementTree.indent(msg.Response)  # for pretty printing
        responseEncoded = ElementTree.tostring(msg.Response, encoding="unicode")
        print("Get Response Message:\n%s" %  responseEncoded)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetAudioDspControls( self, refresh=True) -> bosesoundtouchapi.models.audiodspcontrols.AudioDspControls:

Gets the current audio DSP controls configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A AudioDspControls object that contains audio dsp control configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting audiodspcontrols functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:AudioDspControls = client.GetAudioDspControls()
    print(config.ToString())
    print("\nCurrent Audio DSP Controls Supported Audio Modes array: %s" % (config.ToSupportedAudioModesArray()))

    # get cached configuration, refreshing from device if needed.
    config:AudioDspControls = client.GetAudioDspControls(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.audiodspcontrols.Path in client.ConfigurationCache:
        config:AudioDspControls = client.ConfigurationCache[SoundTouchNodes.audiodspcontrols.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetAudioProductLevelControls( self, refresh=True) -> bosesoundtouchapi.models.audioproductlevelcontrols.AudioProductLevelControls:

Gets the current audio product level controls configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A AudioProductLevelControls object that contains audio product level control configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting audioproductlevelcontrols functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:AudioProductLevelControls = client.GetAudioProductLevelControls()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:AudioProductLevelControls = client.GetAudioProductLevelControls(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.audioproductlevelcontrols.Path in client.ConfigurationCache:
        config:AudioProductLevelControls = client.ConfigurationCache[SoundTouchNodes.audioproductlevelcontrols.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetAudioProductToneControls( self, refresh=True) -> bosesoundtouchapi.models.audioproducttonecontrols.AudioProductToneControls:

Gets the current audio product tone controls configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A AudioProductToneControls object that contains audio product tone control configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting audioproducttonecontrols functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:AudioProductToneControls = client.GetAudioProductToneControls()
    print(config.ToString())

    print("\nBass Range values: %s" % config.Bass.ToMinMaxString())
    print("Treble Range values: %s" % config.Treble.ToMinMaxString())

    # get cached configuration, refreshing from device if needed.
    config:AudioProductToneControls = client.GetAudioProductToneControls(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.audioproducttonecontrols.Path in client.ConfigurationCache:
        config:AudioProductToneControls = client.ConfigurationCache[SoundTouchNodes.audioproducttonecontrols.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetAudioSpeakerAttributeAndSetting( self, refresh=True) -> bosesoundtouchapi.models.audiospeakerattributeandsetting.AudioSpeakerAttributeAndSetting:

Gets the current audio speaker attrribute and setting configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A AudioSpeakerAttributeAndSetting object that contains audio speaker attribute and setting configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting audiospeakerattributeandsetting functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:AudioSpeakerAttributeAndSetting = client.GetAudioSpeakerAttributeAndSetting()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:AudioSpeakerAttributeAndSetting = client.GetAudioSpeakerAttributeAndSetting(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.audiospeakerattributeandsetting.Path in client.ConfigurationCache:
        config:AudioSpeakerAttributeAndSetting = client.ConfigurationCache[SoundTouchNodes.audiospeakerattributeandsetting.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetBalance(self, refresh=True) -> bosesoundtouchapi.models.balance.Balance:

Gets the current balance configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Balance object that contains balance configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    balance:Balance = client.GetBalance()
    print(balance.ToString())
    print("Balance Level = %d" % balance.Actual)

    # get cached configuration, refreshing from device if needed.
    balance:Balance = client.GetBalance(False)
    print("\nCached configuration:\n%s" % balance.ToString())
    print("Balance Level = %d" % balance.Actual)

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.balance.Path in client.ConfigurationCache:
        balance:Balance = client.ConfigurationCache[SoundTouchNodes.balance.Path]
        print("\nCached configuration, direct:\n%s" % balance.ToString())
        print("Balance Level = %d" % balance.Actual)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetBass(self, refresh=True) -> bosesoundtouchapi.models.bass.Bass:

Gets the current bass configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Bass object that contains bass configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    bass:Bass = client.GetBass()
    print(bass.ToString())
    print("Bass Level = %d" % bass.Actual)

    # get cached configuration, refreshing from device if needed.
    bass:Bass = client.GetBass(False)
    print("\nCached configuration:\n%s" % bass.ToString())
    print("Bass Level = %d" % bass.Actual)

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.bass.Path in client.ConfigurationCache:
        bass:Bass = client.ConfigurationCache[SoundTouchNodes.bass.Path]
        print("\nCached configuration, direct:\n%s" % bass.ToString())
        print("Bass Level = %d" % bass.Actual)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetBassCapabilities( self, refresh=True) -> bosesoundtouchapi.models.basscapabilities.BassCapabilities:

Gets the current bass capability configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A BassCapabilities object that contains bass capabilities configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    bassCapabilities:BassCapabilities = client.GetBassCapabilities()
    print(bassCapabilities.ToString())

    # get cached configuration, refreshing from device if needed.
    bassCapabilities:BassCapabilities = client.GetBassCapabilities(False)
    print("\nCached configuration:\n%s" % bassCapabilities.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.bassCapabilities.Path in client.ConfigurationCache:
        bassCapabilities:BassCapabilities = client.ConfigurationCache[SoundTouchNodes.bassCapabilities.Path]
        print("\nCached configuration, direct:\n%s" % bassCapabilities.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetBlueToothInfo( self, refresh=True) -> bosesoundtouchapi.models.bluetoothinfo.BlueToothInfo:

Gets the current bluetooth configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A BlueToothInfo object that contains bluetooth configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:BlueToothInfo = client.GetBlueToothInfo()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:BlueToothInfo = client.GetBlueToothInfo(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.bluetoothInfo.Path in client.ConfigurationCache:
        config:BlueToothInfo = client.ConfigurationCache[SoundTouchNodes.bluetoothInfo.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetCapabilities(self, refresh=True) -> bosesoundtouchapi.models.capabilities.Capabilities:

Gets the current bass capability configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Capabilities object that contains capabilities configuration of the device.

The returned object has a dict-like implementation; individual capabilities can be accessed by typing: GetCapabilities_results['capability_name'].

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    capabilities:Capabilities = client.GetCapabilities()
    print(capabilities.ToString())

    # get cached configuration, refreshing from device if needed.
    capabilities:Capabilities = client.GetCapabilities(False)
    print("\nCached configuration:\n%s" % capabilities.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.capabilities.Path in client.ConfigurationCache:
        capabilities:Capabilities = client.ConfigurationCache[SoundTouchNodes.capabilities.Path]
        print("\nCached configuration, direct:\n%s" % capabilities.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetClockConfig(self, refresh=True) -> bosesoundtouchapi.models.clockconfig.ClockConfig:

Gets the current clock configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A ClockConfig object that contains clock configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    clockConfig:ClockConfig = client.GetClockConfig()
    print(clockConfig.ToString())

    # get cached configuration, refreshing from device if needed.
    clockConfig:ClockConfig = client.GetClockConfig(False)
    print("\nCached configuration:\n%s" % clockConfig.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.clockDisplay.Path in client.ConfigurationCache:
        clockConfig:ClockConfig = client.ConfigurationCache[SoundTouchNodes.clockDisplay.Path]
        print("\nCached configuration, direct:\n%s" % clockConfig.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetClockTime(self, refresh=True) -> bosesoundtouchapi.models.clocktime.ClockTime:

Gets the current clock time configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A ClockTime object that contains clock time configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    clockTime:ClockTime = client.GetClockTime()
    print(clockTime.ToString())

    # get cached configuration, refreshing from device if needed.
    clockTime:ClockTime = client.GetClockTime(False)
    print("\nCached configuration:\n%s" % clockTime.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.clockDisplay.Path in client.ConfigurationCache:
        clockTime:ClockTime = client.ConfigurationCache[SoundTouchNodes.clockDisplay.Path]
        print("\nCached configuration, direct:\n%s" % clockTime.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetDspMono( self, refresh=True) -> bosesoundtouchapi.models.dspmonostereoitem.DSPMonoStereoItem:

Gets the current digital signal processor configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A DSPMonoStereoItem object that contains DSP configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    dspMonoStereoItem:DSPMonoStereoItem = client.GetDspMono()
    print(dspMonoStereoItem.ToString())

    # get cached configuration, refreshing from device if needed.
    dspMonoStereoItem:DSPMonoStereoItem = client.GetDspMono(False)
    print("\nCached configuration:\n%s" % dspMonoStereoItem.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.DSPMonoStereo.Path in client.ConfigurationCache:
        dspMonoStereoItem:DSPMonoStereoItem = client.ConfigurationCache[SoundTouchNodes.DSPMonoStereo.Path]
        print("\nCached configuration, direct:\n%s" % dspMonoStereoItem.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetGroupStereoPairStatus(self, refresh=True) -> bosesoundtouchapi.models.group.Group:

Gets the current left / right stereo pair speaker group configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Group object that contains the result.

The ST-10 is the only SoundTouch product that supports stereo pair groups.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    group:Group = client.GetGroupStereoPairStatus()
    print(group.ToString(True))

    # get cached configuration, refreshing from device if needed.
    group:Group = client.GetGroupStereoPairStatus(False)
    print("\nCached configuration:\n%s" % group.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.getGroup.Path in client.ConfigurationCache:
        group:Group = client.ConfigurationCache[SoundTouchNodes.getGroup.Path]
        print("\nCached configuration, direct:\n%s" % group.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetInformation(self, refresh=True) -> bosesoundtouchapi.models.info.Information:

Gets the information configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Information object that contains the results.

Raises:
  • SoundTouchError: If the device is not capable of supporting info functions, as determined by a query to the cached supportedURLs web-services api.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    info:Information = client.GetInformation()
    print(info.ToString())

    # get cached configuration, refreshing from device if needed.
    info:Information = client.GetInformation(False)
    print("\nCached configuration:\n%s" % info.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.info.Path in client.ConfigurationCache:
        info:Information = client.ConfigurationCache[SoundTouchNodes.info.Path]
        print("\nCached configuration, direct:\n%s" % info.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetIntrospectData(self, introspect: bosesoundtouchapi.models.introspect.Introspect) -> str:

Gets introspect data for a specified source.

Arguments:
  • introspect (Introspect): Introspect object to retrieve introspect data for.
Returns:

A string that contains the introspect xml response.

The introspect xml response returned can vary by source type, and if the source is currently in use (e.g. NowPlaying) or not.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get introspect data for the TUNEIN source.
    introspect:Introspect = Introspect(SoundTouchSources.TUNEIN)
    xmlResponse:str = client.GetIntrospectData(introspect)
    print("\n%s - Response:\n%s" % (introspect.ToString(), xmlResponse))

    # get introspect data for the SPOTIFY source.
    introspect:Introspect = Introspect(SoundTouchSources.SPOTIFY, "SpotifyConnectUserName")
    xmlResponse:str = client.GetIntrospectData(introspect)
    print("\n%s - Response:\n%s" % (introspect.ToString(), xmlResponse))

    # get introspect data for the LOCAL_MUSIC source.
    introspect:Introspect = Introspect(SoundTouchSources.LOCAL_MUSIC, "3f205110-4a57-4e91-810a-ad949d25abb2")
    xmlResponse:str = client.GetIntrospectData(introspect)
    print("\n%s - Response:\n%s" % (introspect.ToString(), xmlResponse))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetLanguage(self, refresh=True) -> bosesoundtouchapi.models.simpleconfig.SimpleConfig:

Gets the current language configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SimpleConfig object that contains language configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    language:SimpleConfig = client.GetLanguage()
    print(language.ToString())
    print("\nDevice Language = '%s'" % language.Value)

    # get cached configuration, refreshing from device if needed.
    language:SimpleConfig = client.GetLanguage(False)
    print("\nCached configuration:\n%s" % language.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.language.Path in client.ConfigurationCache:
        language:SimpleConfig = client.ConfigurationCache[SoundTouchNodes.language.Path]
        print("\nCached configuration, direct:\n%s" % language.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetMediaServerList( self, refresh=True) -> bosesoundtouchapi.models.mediaserverlist.MediaServerList:

Gets the list of UPnP media servers found by the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A MediaServerList object that contains media server configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    mediaServerList:MediaServerList = client.GetMediaServerList()
    print(mediaServerList.ToString(True))

    # get cached configuration, refreshing from device if needed.
    mediaServerList:MediaServerList = client.GetMediaServerList(False)
    print("\nCached configuration:\n%s" % mediaServerList.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.listMediaServers.Path in client.ConfigurationCache:
        mediaServerList:MediaServerList = client.ConfigurationCache[SoundTouchNodes.listMediaServers.Path]
        print("\nCached configuration, direct:\n%s" % mediaServerList.ToString(True))

    # sort the list (in place) by ServerId, ascending order.
    mediaServerList.MediaServers.sort(key=lambda x: (x.ServerId or "").lower(), reverse=False)
    print("\nList sorted by ServerId:\n%s" % mediaServerList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Gets a list of music library data from the specified music library (e.g. STORED_MUSIC, etc).

Arguments:
  • navigate (Navigate): Navigate criteria used to search the music library.
Returns:

A NavigateResponse object that contains the navigation response.

Raises:
  • SoundTouchError: If the device is not capable of supporting navigate functions, as determined by a query to the cached supportedURLs web-services api.

Use the GetSourceList method to get the source and sourceAccount values for the specific NAS Music Library you wish to navigate.

A returned NavigateResponse item can be used to play the item's media content by passing its ContentItem value to the PlayContentItem method.

Music library containers can be traversed by issuing calls to a child container's ContentItem, starting at the Root container.

Music library containers can also be traversed by issuing calls that start at a specific container. For example, lets say you like to listen to songs from your favorite album; you could navigate the container directly if you know the source, sourceAccount, and location values.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # the following shows how to traverse the structure of a NAS Music Library.
    # in this example, my NAS Music Library has the following containers defined:
    # - Root container
    # -- Music
    # ---- Albums
    # ------ Welcome to the New
    # ------ ... and more (albums from other artists)
    # ---- ... and more (Album Artists, All Artists, All Music, Composers, Genre, etc)
    # -- ... and more (Pictures, PlayLists, Videos)

    # set NAS library source to access.
    nasSource:str = SoundTouchSources.STORED_MUSIC.value
    nasSourceAccount:str = "d09708a1-5953-44bc-a413-7d516e04b819/0"
    navItem:NavigateItem = None

    # this example show how to return all tracks for a specific album; it requires that
    # you know the specific name and location of the container as its defined to your library.

    # get NAS library content - static container.
    # the "7_114e8de9" location maps to: Root \ Music \ Albums \ "Welcome to the New" album container.
    staticContainer:NavigateItem = NavigateItem(nasSource, nasSourceAccount, typeValue="dir", name="Welcome to the New", location="7_114e8de9")
    criteria:Navigate = Navigate(nasSource, nasSourceAccount, staticContainer)
    print("\nNavigating Container: '%s' ..." % criteria.ContainerTitle)
    tracksContainer:NavigateResponse = client.GetMusicLibraryItems(criteria)
    for navItem in tracksContainer:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # at this point, I can play any track in the returned results, like so (track 1 selected):
    #client.PlayContentItem(tracksContainer.Items[0].ContentItem)

    # or even play the whole album (parent container):
    #client.PlayContentItem(tracksContainer.Items[0].MediaItemContainer.ContentItem)


    # the following examples show how to navigate your library starting at the root container,
    # and work your way down to a specific album container.

    # get NAS library content - Root container.
    criteria:Navigate = Navigate(nasSource, nasSourceAccount)
    print("\nNavigating Container: '%s' ..." % criteria.ContainerTitle)
    rootContainer:NavigateResponse = client.GetMusicLibraryItems(criteria)
    for navItem in rootContainer:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # get NAS library content - Root \ Music container.
    criteria:Navigate = Navigate(nasSource, nasSourceAccount, rootContainer.GetItemByName("Music"))
    print("\nNavigating Container: '%s' ..." % criteria.ContainerTitle)
    musicContainer:NavigateResponse = client.GetMusicLibraryItems(criteria)
    for navItem in musicContainer:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # get NAS library content - Root \ Music \ Albums container.
    criteria:Navigate = Navigate(nasSource, nasSourceAccount, musicContainer.GetItemByName("Albums"))
    print("\nNavigating Container: '%s' ..." % criteria.ContainerTitle)
    albumsContainer:NavigateResponse = client.GetMusicLibraryItems(criteria)
    for navItem in albumsContainer:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # get NAS library content - Root \ Music \ Albums \ "Welcome to the New" album container.
    criteria:Navigate = Navigate(nasSource, nasSourceAccount, albumsContainer.GetItemByName("Welcome to the New"))
    print("\nNavigating Container: '%s' ..." % criteria.ContainerTitle)
    tracksContainer:NavigateResponse = client.GetMusicLibraryItems(criteria)
    for navItem in tracksContainer:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # sort the results (in place) by Name, ascending order.
    tracksContainer.Items.sort(key=lambda x: (x.ContentItem.Name or "").lower(), reverse=True)
    print("\nList sorted by Name descending:")
    for navItem in tracksContainer:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Gets a list of your stored stations from the specified music service (e.g. PANDORA, etc).

Arguments:
  • navigate (Navigate): Navigate criteria used to search the music service.
Returns:

A NavigateResponse object that contains the navigation response.

Raises:
  • SoundTouchError: If the device is not capable of supporting navigate functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get my collection of PANDORA music service stations.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId")
    results:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\nMy %s Music Service Stations:\n%s" % (results.Source, results.ToString(True)))

    # get my PANDORA music service content - sort by date created, descending.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId")
    results:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\nMy %s Music Service Stations (sorted by DateCreated DESC):\n%s" % (results.Source, results.ToString(True)))

    # get my PANDORA music service content - sort by station name, ascending.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId", sortType=NavigateSortTypes.StationName)
    results:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\nMy %s Music Service Stations (sorted by StationName ASC):\n%s" % (results.Source, results.ToString(True)))

    # sort the results (in place) by Name, descending order.
    results.Items.sort(key=lambda x: (x.Name or "").lower(), reverse=True)
    print("\nList sorted by Name descending:\n%s" % results.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetName(self, refresh=True) -> bosesoundtouchapi.models.simpleconfig.SimpleConfig:

Gets the current name configuration of the device, and updates the SoundTouchDevice class device name if possible.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SimpleConfig object that contains name configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    name:SimpleConfig = client.GetName()
    print(name.ToString())
    print("\nDevice Name = '%s'" % name.Value)

    # get cached configuration, refreshing from device if needed.
    name:SimpleConfig = client.GetName(False)
    print("\nCached configuration:\n%s" % name.ToString())
    print("\nDevice Name = '%s'" % name.Value)

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.name.Path in client.ConfigurationCache:
        name:SimpleConfig = client.ConfigurationCache[SoundTouchNodes.name.Path]
        print("\nCached configuration, direct:\n%s" % name.ToString())
        print("\nDevice Name = '%s'" % name.Value)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetNetworkInfo(self, refresh=True) -> bosesoundtouchapi.models.networkinfo.NetworkInfo:

Gets the current network information configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A NetworkInfo object that contains network information configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    networkInfo:NetworkInfo = client.GetNetworkInfo()
    print(networkInfo.ToString(True))

    # get cached configuration, refreshing from device if needed.
    networkInfo:NetworkInfo = client.GetNetworkInfo(False)
    print("\nCached configuration:\n%s" % networkInfo.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.networkInfo.Path in client.ConfigurationCache:
        networkInfo:NetworkInfo = client.ConfigurationCache[SoundTouchNodes.networkInfo.Path]
        print("\nCached configuration, direct:\n%s" % networkInfo.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetNetworkStatus( self, refresh=True) -> bosesoundtouchapi.models.networkstatus.NetworkStatus:

Gets the current network status configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A NetworkStatus object that contains network status configuration of the device.

This method can be used to retrieve the network status of the device for each network interface that has established a connection. This includes details like the interface name (e.g. 'eth0'), the network SSID, MAC Address, and more.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    networkStatus:NetworkStatus = client.GetNetworkStatus()
    print(networkStatus.ToString(True))

    # get cached configuration, refreshing from device if needed.
    networkStatus:NetworkStatus = client.GetNetworkStatus(False)
    print("\nCached configuration:\n%s" % networkStatus.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.netStats.Path in client.ConfigurationCache:
        networkStatus:NetworkStatus = client.ConfigurationCache[SoundTouchNodes.netStats.Path]
        print("\nCached configuration, direct:\n%s" % networkStatus.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetNowPlayingStatus( self, refresh=True) -> bosesoundtouchapi.models.nowplayingstatus.NowPlayingStatus:

Gets the now playing status configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A NowPlayingStatus object that contains now playing status configuration of the device.

This method can be used to retrieve the status of media that is currently playing on the device. This includes the media source, ContentItem, track, artist, album, preview image, duration, position, play status, shuffle and repeat setting, stream type, track ID, station description and the location of the station.

Some special nodes of interest:

  • <isAdvertisement /> node will be present if the currently playing media content is an advertidement.
  • <isFavorite /> node will be present if the currently playing media content is marked as a favorite.
  • <favoriteEnabled /> node will be present if the currently playing media content can be marked as a favorite.
  • <rateEnabled /> node will be present if the currently playing media content can be rated (e.g. thumbs up, down).
  • <skipEnabled /> node will be present if the currently playing media content supports skip control.
  • <shuffleSetting> node will be present if the currently playing media supports shuffle mode.
  • <repeatSetting> node will be present if the currently playing media supports repeat mode.
  • <time> node (e.g. current play position and duration) will only update the position value every 30 seconds for devices that are members of a zone, while the master zone will update the position value every second.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    nowPlayingStatus:NowPlayingStatus = client.GetNowPlayingStatus()
    print(nowPlayingStatus.ToString())

    # get cached configuration, refreshing from device if needed.
    nowPlayingStatus:NowPlayingStatus = client.GetNowPlayingStatus(False)
    print("\nCached configuration:\n%s" % nowPlayingStatus.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.nowPlaying.Path in client.ConfigurationCache:
        nowPlayingStatus:NowPlayingStatus = client.ConfigurationCache[SoundTouchNodes.nowPlaying.Path]
        print("\nCached configuration, direct:\n%s" % nowPlayingStatus.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetOptions(self, uri: bosesoundtouchapi.uri.soundtouchuri.SoundTouchUri) -> list:

Makes an OPTIONS request and returns the list of available HTTP-Methods.

Use this method when testing whether a node can be accessed.

Arguments:
  • uri (SoundTouchUri): The node where the requested value is stored.
Returns:

A list of strings storing all available HTTP-Methods.

Raises:
  • SoundTouchError: When errors should not be ignored on this client, they will raise a SoundTouchError exception with all information related to that error.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # list available HTTP-Methods for a specific node.
    node:SoundTouchUri = SoundTouchNodes.volume
    methods:list = client.GetOptions(node)
    print("Options for '%s' node: %s" % (node.Path, str(methods)))

    # list available HTTP-Methods for ALL nodes supported by the device.
    node:SoundTouchUri
    for node in device.SupportedUris:
        methods:list = client.GetOptions(node)
        print("Options for '%s' node: %s" % (node.Path, str(methods)))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetPowerManagement( self, refresh=True) -> bosesoundtouchapi.models.powermanagement.PowerManagement:

Gets the current power management status configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A PowerManagement object that contains power management configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    powerManagement:PowerManagement = client.GetPowerManagement()
    print(powerManagement.ToString())

    # get cached configuration, refreshing from device if needed.
    powerManagement:PowerManagement = client.GetPowerManagement(False)
    print("\nCached configuration:\n%s" % powerManagement.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.powerManagement.Path in client.ConfigurationCache:
        powerManagement:PowerManagement = client.ConfigurationCache[SoundTouchNodes.powerManagement.Path]
        print("\nCached configuration, direct:\n%s" % powerManagement.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetPresetList( self, refresh=True, resolveSourceTitles: bool = False) -> bosesoundtouchapi.models.presetlist.PresetList:

Gets the current preset list configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
  • resolveSourceTitles (bool): True to resolve the SourceTitle property value for all preset items in the list; otherwise, False to return the list without source titles.
Returns:

A PresetList object that contains preset list configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    presetList:PresetList = client.GetPresetList()
    print(presetList.ToString(True))

    # get cached configuration, refreshing from device if needed.
    presetList:PresetList = client.GetPresetList(False)
    print("\nCached configuration:\n%s" % presetList.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.presets.Path in client.ConfigurationCache:
        presetList:PresetList = client.ConfigurationCache[SoundTouchNodes.presets.Path]
        print("\nCached configuration, direct:\n%s" % presetList.ToString(True))

    # sort the list (in place) by Name, ascending order.
    presetList.Presets.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
    print("\nList sorted by Name:\n%s" % presetList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetProductCecHdmiControl( self, refresh=True) -> bosesoundtouchapi.models.productcechdmicontrol.ProductCecHdmiControl:

Gets the current product CEC HDMI control configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A ProductCecHdmiControl object that contains product CEC HDMI control configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting productcechdmicontrol functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:ProductCecHdmiControl = client.GetProductCecHdmiControl()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:ProductCecHdmiControl = client.GetProductCecHdmiControl(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.productcechdmicontrol.Path in client.ConfigurationCache:
        config:ProductCecHdmiControl = client.ConfigurationCache[SoundTouchNodes.productcechdmicontrol.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetProductHdmiAssignmentControls( self, refresh=True) -> bosesoundtouchapi.models.producthdmiassignmentcontrols.ProductHdmiAssignmentControls:

Gets the current product HDMI assignment controls configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A ProductHdmiAssignmentControls object that contains product HDMI assignment control configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting producthdmiassignmentcontrols functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:ProductHdmiAssignmentControls = client.GetProductHdmiAssignmentControls()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:ProductHdmiAssignmentControls = client.GetProductHdmiAssignmentControls(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.producthdmiassignmentcontrols.Path in client.ConfigurationCache:
        config:ProductHdmiAssignmentControls = client.ConfigurationCache[SoundTouchNodes.producthdmiassignmentcontrols.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetProperty( self, uri: bosesoundtouchapi.uri.soundtouchuri.SoundTouchUri, classType, refresh=True):

Returns a cached property mapped to the given URI.

Arguments:
  • uri (SoundTouchUri): The property key (e.g. 'balance', 'volume', etc).
  • classType (type): The configuration class type (e.g. Balance, Volume, etc).
  • refresh (bool): True to refresh the property with real-time information from the device; otherwise, False to just return the cached value.
Returns:

A configuration instance of the provided classType argument.

This method will refresh the property from the device if the property does not exist in the cache, regardless of the refresh argument value.

def GetReBroadcastLatencyMode( self, refresh=True) -> bosesoundtouchapi.models.rebroadcastlatencymode.RebroadcastLatencyMode:

Gets the current rebroadcast latency mode configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A RebroadcastLatencyMode object that contains rebroadcast latency mode configuration of the device IF the device supports it; otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting rebroadcastlatencymode functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    # note that not all devices support retrieval of this information.
    config:RebroadcastLatencyMode = client.GetReBroadcastLatencyMode()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:RebroadcastLatencyMode = client.GetReBroadcastLatencyMode(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.rebroadcastlatencymode.Path in client.ConfigurationCache:
        config:RebroadcastLatencyMode = client.ConfigurationCache[SoundTouchNodes.rebroadcastlatencymode.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetRecentList( self, refresh=True, resolveSourceTitles: bool = False, filterSourceTitle: str = None) -> bosesoundtouchapi.models.recentlist.RecentList:

Gets the current recent list configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
  • resolveSourceTitles (bool): True to resolve the SourceTitle property value for all recent items in the list; otherwise, False to return the list without source titles.
  • filterSourceTitle (str): Limits the results of the recents list to the specified source title. Setting this argument automatically sets the resolveSourceTitles argument to True. The value specified is case-sensitive when comparing to the list items.
Returns:

A RecentList object that contains recent list configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    recentList:RecentList = client.GetRecentList()
    print(recentList.ToString(True))

    # get cached configuration, refreshing from device if needed.
    recentList:RecentList = client.GetRecentList(False)
    print("\nCached configuration:\n%s" % recentList.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.recents.Path in client.ConfigurationCache:
        recentList:RecentList = client.ConfigurationCache[SoundTouchNodes.recents.Path]
        print("\nCached configuration, direct:\n%s" % recentList.ToString(True))

    # sort the list (in place) by Name, ascending order.
    recentList.Recents.sort(key=lambda x: (x.Name or "").lower(), reverse=False)
    print("\nList sorted by Name:\n%s" % recentList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetRequestToken(self, refresh=True) -> bosesoundtouchapi.models.simpleconfig.SimpleConfig:

Gets a new bearer token generated by the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SimpleConfig object that contains the request token in the Attribute property.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    requestToken:SimpleConfig = client.GetRequestToken()
    print(requestToken.ToString())
    print("\nToken = '%s'" % requestToken.Attribute['value'])

    # get cached configuration, refreshing from device if needed.
    requestToken:SimpleConfig = client.GetRequestToken(False)
    print("\nCached configuration:\n%s" % requestToken.ToString())
    print("\nToken = '%s'" % requestToken.Attribute['value'])

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.requestToken.Path in client.ConfigurationCache:
        requestToken:SimpleConfig = client.ConfigurationCache[SoundTouchNodes.requestToken.Path]
        print("\nCached configuration, direct:\n%s" % requestToken.ToString())
        print("\nToken = '%s'" % requestToken.Attribute['value'])

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetServiceAvailability( self, refresh=True) -> bosesoundtouchapi.models.serviceAvailability.ServiceAvailability:

Gets the current service availability configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A ServiceAvailability object that contains service availability configuration of the device.

Raises:
  • SoundTouchError: If the device is not capable of supporting serviceAvailability functions, as determined by a query to the cached supportedURLs web-services api.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:ServiceAvailability = client.GetServiceAvailability()
    print(config.ToString(True))

    # get cached configuration, refreshing from device if needed.
    config:ServiceAvailability = client.GetServiceAvailability(False)
    print("\nCached configuration:\n%s" % config.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.serviceAvailability.Path in client.ConfigurationCache:
        config:ServiceAvailability = client.ConfigurationCache[SoundTouchNodes.serviceAvailability.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString(True))

    # sort the list (in place) by ServiceType, ascending order.
    config.Services.sort(key=lambda x: (x.ServiceType or "").lower(), reverse=False)
    print("\nList sorted by ServiceType:\n%s" % config.ToString(True))

    # sort the list (in place) by IsAvailable, ascending order.
    config.Services.sort(key=lambda x: x.IsAvailable or False, reverse=False)
    print("\nList sorted by IsAvailable:\n%s" % config.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetSoftwareUpdateStatus( self, refresh=True) -> bosesoundtouchapi.models.softwareupdatequeryresponse.SoftwareUpdateQueryResponse:

Gets the status of a SoundTouch software update for the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SoftwareUpdateQueryResponse object that contains software update status configuration of the device IF the device supports it; otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting swUpdateQuery functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:SoftwareUpdateQueryResponse = client.GetSoftwareUpdateStatus()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:SoftwareUpdateQueryResponse = client.GetSoftwareUpdateStatus(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.swUpdateQuery.Path in client.ConfigurationCache:
        config:SoftwareUpdateQueryResponse = client.ConfigurationCache[SoundTouchNodes.swUpdateQuery.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetSoftwareUpdateCheckInfo( self, refresh=True) -> bosesoundtouchapi.models.softwareupdatecheckresponse.SoftwareUpdateCheckResponse:

Gets the latest available software update release version information for the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SoftwareUpdateCheckResponse object that contains software release information configuration of the device IF the device supports it; otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting swUpdateCheck functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:SoftwareUpdateCheckResponse = client.GetSoftwareUpdateCheckInfo()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:SoftwareUpdateCheckResponse = client.GetSoftwareUpdateCheckInfo(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.swUpdateCheck.Path in client.ConfigurationCache:
        config:SoftwareUpdateCheckResponse = client.ConfigurationCache[SoundTouchNodes.swUpdateCheck.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetSoundTouchConfigurationStatus( self, refresh=True) -> bosesoundtouchapi.models.soundtouchconfigurationstatus.SoundTouchConfigurationStatus:

Gets the current SoundTouch configuration status configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SoundTouchConfigurationStatus object that contains SoundTouch configuration status of the device.

Raises:
  • SoundTouchError: If the device is not capable of supporting soundTouchConfigurationStatus functions, as determined by a query to the cached supportedURLs web-services api.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:SoundTouchConfigurationStatus = client.GetSoundTouchConfigurationStatus()
    print(config.ToString())

    # get cached configuration, refreshing from device if needed.
    config:SoundTouchConfigurationStatus = client.GetSoundTouchConfigurationStatus(False)
    print("\nCached configuration:\n%s" % config.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.soundTouchConfigurationStatus.Path in client.ConfigurationCache:
        config:SoundTouchConfigurationStatus = client.ConfigurationCache[SoundTouchNodes.soundTouchConfigurationStatus.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetSourceList(self, refresh=True) -> bosesoundtouchapi.models.sourcelist.SourceList:

Gets the current source list configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SourceList object that contains source list configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    sourceList:SourceList = client.GetSourceList()
    print(sourceList.ToString(True))

    # get source list array.
    print("\nSourceArray:\n%s" % sourceList.ToSourceArray())

    # get source:account list array.
    print("\nSourceArray (with Account):\n%s" % sourceList.ToSourceArray(True))

    # get specific sourceitem with the source name.
    sourceItem = sourceList['TUNEIN']
    print("(by name 'TUNEIN')  %s" % (sourceItem.ToString()))

    # get specific sourceitem at the index position.
    sourceItem = sourceList[0]
    print("(by index 0)        %s" % (sourceItem.ToString()))

    # get cached configuration, refreshing from device if needed.
    sourceList:SourceList = client.GetSourceList(False)
    print("\nCached configuration:\n%s" % sourceList.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.sources.Path in client.ConfigurationCache:
        sourceList:SourceList = client.ConfigurationCache[SoundTouchNodes.sources.Path]
        print("\nCached configuration, direct:\n%s" % sourceList.ToString(True))

    # sort the list (in place) by SourceAccount, ascending order.
    sourceList.SourceItems.sort(key=lambda x: (x.SourceAccount or "").lower(), reverse=False)
    print("\nList sorted by SourceAccount:\n%s" % sourceList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetSupportedUrls( self, refresh=True) -> bosesoundtouchapi.models.supportedurls.SupportedUrls:

Gets the supported urls configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SupportedUrls object that contains the results.

Raises:
  • SoundTouchError: If the device is not capable of supporting info functions, as determined by a query to the cached supportedURLs web-services api.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:SupportedUrls = client.GetSupportedUrls()
    print(config.ToString(True))

    # get cached configuration, refreshing from device if needed.
    config:SupportedUrls = client.GetSupportedUrls(False)
    print("\nCached configuration:\n%s" % config.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.supportedURLs.Path in client.ConfigurationCache:
        config:SupportedUrls = client.ConfigurationCache[SoundTouchNodes.supportedURLs.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetSystemTimeout( self, refresh=True) -> bosesoundtouchapi.models.systemtimeout.SystemTimeout:

Gets the current system timeout configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A SystemTimeout object that contains system timeout configuration of the device.

Use this method to determine whether power saving is enabled or not.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    systemTimeout:SystemTimeout = client.GetSystemTimeout()
    print(systemTimeout.ToString())

    # get cached configuration, refreshing from device if needed.
    systemTimeout:SystemTimeout = client.GetSystemTimeout(False)
    print("\nCached configuration:\n%s" % systemTimeout.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.systemtimeout.Path in client.ConfigurationCache:
        systemTimeout:SystemTimeout = client.ConfigurationCache[SoundTouchNodes.systemtimeout.Path]
        print("\nCached configuration, direct:\n%s" % systemTimeout.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetTrackInfo(self, refresh=True) -> bosesoundtouchapi.models.trackinfo.TrackInfo:

Gets extended track information for the current playing music service media.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A TrackInfo object that contains track information.

Raises:
  • SoundTouchError: If the device is not capable of supporting trackInfo functions, as determined by a query to the cached supportedURLs web-services api.

This method only returns information if the currently playing content is from a music service source (e.g. PANDORA, SPOTIFY, etc). If currently playing media is NOT from a music service source (e.g. AIRPLAY, STORED_MUSIC, etc) then the SoundTouch webservice will become unresponsive (e.g. hangs) for about 30 seconds until it times out with an error status.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    trackInfo:TrackInfo = client.GetTrackInfo()
    print(trackInfo.ToString())

    # get cached configuration, refreshing from device if needed.
    trackInfo:TrackInfo = client.GetTrackInfo(False)
    print("\nCached configuration:\n%s" % trackInfo.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.trackInfo.Path in client.ConfigurationCache:
        trackInfo:TrackInfo = client.ConfigurationCache[SoundTouchNodes.trackInfo.Path]
        print("\nCached configuration, direct:\n%s" % trackInfo.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetVolume(self, refresh=True) -> bosesoundtouchapi.models.volume.Volume:

Gets the current volume configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Volume object that contains volume configuration of the device.

The Target and Actual returned values will only be different when the volume is changing.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print(volume.ToString())
    print("Volume Level = %d" % volume.Actual)

    # get cached configuration, refreshing from device if needed.
    volume:Volume = client.GetVolume(False)
    print("\nCached configuration:\n%s" % volume.ToString())
    print("Volume Level = %d" % volume.Actual)

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.volume.Path in client.ConfigurationCache:
        volume:Volume = client.ConfigurationCache[SoundTouchNodes.volume.Path]
        print("\nCached configuration, direct:\n%s" % volume.ToString())
        print("Volume Level = %d" % volume.Actual)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetWirelessProfile( self, refresh=True) -> bosesoundtouchapi.models.wirelessprofile.WirelessProfile:

Gets the current wireless profile configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A WirelessProfile object that contains wireless profile configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    wirelessProfile:WirelessProfile = client.GetWirelessProfile()
    print(wirelessProfile.ToString())

    # get cached configuration, refreshing from device if needed.
    wirelessProfile:WirelessProfile = client.GetWirelessProfile(False)
    print("\nCached configuration:\n%s" % wirelessProfile.ToString())

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.getActiveWirelessProfile.Path in client.ConfigurationCache:
        wirelessProfile:WirelessProfile = client.ConfigurationCache[SoundTouchNodes.getActiveWirelessProfile.Path]
        print("\nCached configuration, direct:\n%s" % wirelessProfile.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

Gets a list of wireless networks that can be detected by the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A PerformWirelessSiteSurveyResponse object that contains wireless survey configuration of the device IF the device supports it (e.g. ST-300, etc); otherwise, None if the device does not support it.

Raises:
  • SoundTouchError: If the device is not capable of supporting performWirelessSiteSurvey functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    config:PerformWirelessSiteSurveyResponse = client.GetWirelessSiteSurvey()
    print(config.ToString(True))

    # get cached configuration, refreshing from device if needed.
    config:PerformWirelessSiteSurveyResponse = client.GetWirelessSiteSurvey(False)
    print("\nCached configuration:\n%s" % config.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.performWirelessSiteSurvey.Path in client.ConfigurationCache:
        config:PerformWirelessSiteSurveyResponse = client.ConfigurationCache[SoundTouchNodes.performWirelessSiteSurvey.Path]
        print("\nCached configuration, direct:\n%s" % config.ToString(True))

    # sort the list (in place) by SignalStrength, ascending order.
    config.SurveyResultItems.sort(key=lambda x: x.SignalStrength or 0, reverse=False)
    print("\nList sorted by SignalStrength:\n%s" % config.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def GetZoneStatus(self, refresh=True) -> bosesoundtouchapi.models.zone.Zone:

Gets the current wireless zone status configuration of the device.

Arguments:
  • refresh (bool): True to query the device for realtime information and refresh the cache; otherwise, False to just return the cached information.
Returns:

A Zone object that contains zone configuration of the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    zone:Zone = client.GetZoneStatus()
    print(zone.ToString(True))

    # get cached configuration, refreshing from device if needed.
    zone:Zone = client.GetZoneStatus(False)
    print("\nCached configuration:\n%s" % zone.ToString(True))

    # get cached configuration directly from the configuration manager dictionary.
    if SoundTouchNodes.getZone.Path in client.ConfigurationCache:
        zone:Zone = client.ConfigurationCache[SoundTouchNodes.getZone.Path]
        print("\nCached configuration, direct:\n%s" % zone.ToString(True))


except Exception as ex:

    print("** Exception: %s" % str(ex))

def MakeRequest( self, method: str, msg: bosesoundtouchapi.soundtouchmessage.SoundTouchMessage) -> int:

Performs a generic request by converting the response into the message object.

Arguments:
  • method (str): The preferred HTTP method (e.g. "GET", "POST", etc).
  • msg (SoundTouchMessage): The altered message object.
Returns:

The status code (integer) or allowed methods (list).

Raises:
  • SoundTouchError: If an error occurs while requesting content.

A 400 status code is immediately returned for the following scenarios:

  • The method argument is not supplied.
  • The msg argument is not supplied.
  • The msg.Uri is not in the device list of supported URI's.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # manually make a request to the volume status node.
    volume:Volume = Volume(25)
    print("\nVolume object:\n%s" % volume.ToString())
    reqBody:str = volume.ToXmlRequestBody()
    message = SoundTouchMessage(SoundTouchNodes.volume, reqBody)
    client.MakeRequest('POST', message)
    print("\nMakeRequest Response:\n%s" % message.XmlMessage)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaNextTrack(self) -> None:

Move to the next track in the current media playlist.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are skip next functions allowed for currently playing media?
    if nowPlaying.IsSkipEnabled:

        # move to the next track in the current media playlist.
        client.MediaNextTrack()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Skip Next functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaPause(self) -> None:

Pause the current media playing.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # pause currently playing media.
    client.MediaPause()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaPlay(self) -> None:

Play the currently paused media.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # play currently paused media.
    client.MediaPlay()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaPlayPause(self) -> None:

Toggle the Play / Pause state of the current media playing.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # toggle the play / pause state of the current media playing.
    client.MediaPlayPause()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaPreviousTrack(self, force: bool = False) -> None:

Play previous track if current track has been playing for less than 10 seconds; otherwise, restart play of the current track.

Arguments:
  • force (bool): If True, force the previous track to be played regardless of how much play time has passed for the current track; otherwise, False to restart the current track if more than 10 seconds have passed.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are skip previous functions allowed for currently playing media?
    if nowPlaying.IsSkipPreviousEnabled:

        # move to the previous track in the current media playlist.
        client.MediaPreviousTrack()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Skip Previous functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaRepeatAll(self) -> None:

Enables repeat all processing for the current media playlist.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are repeat functions allowed for currently playing media?
    if nowPlaying.IsRepeatEnabled:

        # enable repeat all processing for the current media playlist.
        client.MediaRepeatAll()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Repeat functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaRepeatOff(self) -> None:

Turns off repeat (all / one) processing for the current media playlist.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are repeat functions allowed for currently playing media?
    if nowPlaying.IsRepeatEnabled:

        # disable repeat (all / one) processing for the current media playlist.
        client.MediaRepeatOff()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Repeat functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaRepeatOne(self) -> None:

Enables repeat single track processing for the current media playlist.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are repeat functions allowed for currently playing media?
    if nowPlaying.IsRepeatEnabled:

        # enable repeat one processing for the current media playlist.
        client.MediaRepeatOne()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Repeat functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaResume(self) -> None:

Resume the current media playing.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # resume currently playing media.
    client.MediaResume()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaSeekToTime(self, startSecond: int = 1, delay: int = 1) -> None:

Start playing the current media at the specified position in seconds (e.g. seek to time).

Arguments:
  • startSecond (int): Starting position (in seconds) of where to start playing the media content.
  • delay (int): Time delay (in seconds) to wait AFTER changing the track position.
    This delay will give the device time to process the change before another command is accepted.
    Default is 1; value range is 0 - 10.

The now playing media must support seek operations for this method to be successful. Query the NowPlayingStatus.IsSeekSupported flag to verify if seek operations are supported for the currently playing media.

The track position is not changed if the startSecond argument falls outside of the current media total track time.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s'" % (nowPlaying.ToString()))
    print("\nIsSeekSupported = '%s'" % nowPlaying.IsSeekSupported)
    print("Position Setting Before = %s" % str(nowPlaying.Position))

    # is seek function allowed for currently playing media?
    if nowPlaying.IsSeekSupported:

        # start playing media at the specified position (in seconds).
        print("Seeking to position = 10 ...")
        client.MediaSeekToTime(10)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("Position Setting After  = %s" % str(nowPlaying.Position))
        print("\n(after ): '%s'" % (nowPlaying.ToString()))

    else:

        print("\n** Seek function not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaShuffleOff(self) -> None:

Disables shuffling of the current media playlist.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are shuffle functions allowed for currently playing media?
    if nowPlaying.IsShuffleEnabled:

        # disable shuffling of the current media playlist. 
        client.MediaShuffleOff()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Shuffle functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaShuffleOn(self) -> None:

Enables shuffling of the current media playlist.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # are shuffle functions allowed for currently playing media?
    if nowPlaying.IsShuffleEnabled:

        # enable shuffling of the current media playlist. 
        client.MediaShuffleOn()

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    else:

        print("\n** Shuffle functions not available for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MediaStop(self) -> None:

Stop the current media playing.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # stop currently playing media.
    client.MediaStop()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def Mute(self) -> None:

Toggle mute / unmute.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(before) %s" % volume.ToString())

    # toggle mute / unmute of the device.
    client.Mute()

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(after)  %s" % volume.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MuteOff(self, refresh: bool = True) -> None:

Unmutes the device, if the device is currently muted.

Arguments:
  • refresh (bool): True to check the real-time status of the device; otherwise, False to check the cached status of the device.
    Default = True.

This will first issue a GetVolume() method call to query the current volume of the device. If the refresh argument is True, then the volume status is refreshed with real-time data; otherwise the cached volume status is used.

If the volume IsMuted property is true, then the MUTE key will be sent to unmute the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(before) %s" % volume.ToString())

    # unmute device.
    client.MuteOff()

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(after)  %s" % volume.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def MuteOn(self, refresh: bool = True) -> None:

Mutes the device, if the device is currently not muted.

Arguments:
  • refresh (bool): True to check the real-time status of the device; otherwise, False to check the cached status of the device.
    Default = True.

This will first issue a GetVolume() method call to query the current volume of the device. If the refresh argument is True, then the volume status is refreshed with real-time data; otherwise the cached volume status is used.

If the volume IsMuted property is false, then the MUTE key will be sent to mute the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(before) %s" % volume.ToString())

    # mute device.
    client.MuteOn()

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(after)  %s" % volume.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

Plays the given ContentItem.

Arguments:
  • item (ContentItem): Content item to play.
  • delay (int): Time delay (in seconds) to wait AFTER selecting the content item.
    This delay will give the device time to process the change before another command is accepted.
    Default is 5; value range is 0 - 10.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): %s" % (nowPlaying.ToString()))

    # play the specified media content.
    content_item_radio:ContentItem = ContentItem("TUNEIN","stationurl","/v1/playback/station/s309605","",True,"K-LOVE 90s")
    client.PlayContentItem(content_item_radio)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  %s" % (nowPlaying.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PlayNotificationBeep(self) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Plays a notification beep on the device. This will cause device to pause the currently playing media, emit a double beep sound, and then resume the media play.

Raises:
  • SoundTouchError: If the device is not capable of supporting playNotification functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-10 will support this, but the ST-300 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

import time
from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # play a notification beep.
    print("\nPlaying notification beep ...")
    client.PlayNotificationBeep()

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PlayNotificationTTS( self, sayText: str, ttsUrl: str = None, artist: str = None, album: str = None, track: str = None, volumeLevel: int = 0, appKey: str = None) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Plays a notification message via Google TTS (Text-To-Speech) processing.

Arguments:
  • sayText (str): The message that will be converted from text to speech and played on the device.
  • ttsUrl (str): The Text-To-Speech url used to translate the message.
    The value should contain a "{saytext}" format parameter, that will be used to insert the encoded sayText value. Default value is:
    "http://translate.google.com/translate_tts?ie=UTF-8&tl=EN&client=tw-ob&q={saytext}"
  • artist (str): The message text that will appear in the NowPlaying Artist node.
    Default is "TTS Notification"
  • album (str): The message text that will appear in the NowPlaying Album node.
    Default is "Google TTS"
  • track (str): The message text that will appear in the NowPlaying Track node.
    Default is the sayText argument value.
  • volumeLevel (int): The temporary volume level that will be used when the message is played.
    Specify a value of zero to play at the current volume.
    Per Bose limitations, max level cannot be more than 70. Default is zero.
  • appKey (str): Bose Developer API application key.
Raises:
  • SoundTouchError: ttsUrl argument value does not start with 'http://'. ttsUrl argument was not a string; ignoring PlayNotificationTTS request.

The notification message is played at the level specified by the volumeLevel argument. Specify a volumeLevel of zero to play the notification at the current volume level. The volume level is restored to the level it was before the notification message was played after the notification is complete; e.g. if you made changes to the volume while the notification is playing then they are changed back to the volume level that was in effect prior to playing the notification. The SoundTouch device automatically takes care of the volume level switching; there are no calls in the method to change the volume or currently playing content status. The SoundTouch device also limits the volume range between 10 (min) and 70 (max); this is a Bose limitation, and is not imposed by this API.

The currently playing content (if any) is paused while the notification message content is played, and then resumed once the notification ends.

The <service> node content will appear in the NowPlaying status <artist> node.
The <message> node content will appear in the NowPlaying status <album> node.
The <reason> node content will appear in the NowPlaying status <track> node.

If the device is the master controller of a zone, then the notification message will be played on all devices that are members of the zone.

A small delay can be inserted at the start of the message by prefixing the sayText argument value with "a!". Example: "a!This is a test message". It's not a perfect solution, but works for me since my SoundTouch speaker takes a second or two to switch into active mode, and the first second of the played message is lost.

This method calls the play_info SoundTouch API service for the notification. There are models of SoundTouch speakers that do not support notifications. Per the SoundTouch WebServices API reference: audio Notifications are only available for SoundTouch 10, SoundTouch 20 Series III, and SoundTouch 30 Series III. Attempting to send an Audio Notification to an incompatible device will return a 403 Forbidden error.

Sample Code

import time
from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # use google text to speech to say a message.
    print("\nSaying message via Google TTS (language=EN) ...")
    client.PlayNotificationTTS("There is activity at the front door.")

    # if playing messages back to back, then give the message time to play
    # before playing the next one; otherwise the next message is lost.
    time.sleep(6)

    # use google text to speech to say a message.
    print("\nSaying message via Google TTS (language=DE) ...")
    client.PlayNotificationTTS("There is activity at the front door.", 
                               "http://translate.google.com/translate_tts?ie=UTF-8&tl=DE&client=tw-ob&q={saytext}",
                               volumeLevel=30)

    # if playing messages back to back, then give the message time to play
    # before playing the next one; otherwise the next message is lost.
    time.sleep(6)

    # use google text to speech to say a message.
    print("\nSaying message via Google TTS (language=EN) ...")
    client.PlayNotificationTTS("There is activity at the front door.", 
                               "http://translate.google.com/translate_tts?ie=UTF-8&tl=EN&client=tw-ob&q={saytext}",
                               "Activity Detected", # <- appears in nowPlaying.Artist
                               "Front Door",        # <- appears in nowPlaying.Album
                               "Motion Sensor",     # <- appears in nowPlaying.Track
                               volumeLevel=20)

    # if playing messages back to back, then give the message time to play
    # before playing the next one; otherwise the next message is lost.
    time.sleep(6)

    # use google text to speech to say a message using a custom Bose developer appKey.
    print("\nSaying message via Google TTS (language=EN) ...")
    client.PlayNotificationTTS("There is activity at the front door.", 
                               appKey="YourBoseAppKey")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PlayUrl( self, url: str, artist: str = None, album: str = None, track: str = None, volumeLevel: int = 0, appKey: str = None, getMetaDataFromUrlFile: bool = False) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Plays media from the given URL.

Arguments:
  • url (str): The url to play.
  • artist (str): The message text that will appear in the NowPlaying Artist node.
    Default is "Unknown Artist"
  • album (str): The message text that will appear in the NowPlaying Album node.
    Default is "Unknown Album"
  • track (str): The message text that will appear in the NowPlaying Track node.
    Default is "Unknown Track"
  • volumeLevel (int): The temporary volume level that will be used when the media is played.
    Specify a value of zero to play at the current volume.
    Default is zero.
  • appKey (str): Bose Developer API application key.
  • getMetaDataFromUrlFile (bool): If true, the artist, album, and song title metadata details will be retrieved from the ID3 header of the url content (if available); otherwise, False to use the artist, album, and song title arguments specified.

Returns:
A SoundTouchMessage object storing the request uri, a payload that has been sent (optional), and the response as an xml.etree.ElementTree.Element.

Raises:
  • SoundTouchError: Url argument value does not start with 'http://' or 'https://'.
    If the SoundTouch device encounters an error while trying to play the url media content.

The given url content is played at the level specified by the volumeLevel argument. Specify a volumeLevel of zero to play the given url content at the current volume level. The volume level is restored to the level it was before the given url content was played after play is complete; e.g. if you made changes to the volume while the given url content is playing then they are changed back to the volume level that was in effect prior to playing the given url content. The SoundTouch device automatically takes care of the volume level switching; there are no calls in the method to change the volume or currently playing content status.

The currently playing content (if any) is paused while the given url content is played, and then resumed once the given url content ends. If the currently playing content is a url (or other "notification" source type), then the MediaNextTrack method will be called to stop the current play and the new source will be played.

If the device is the master controller of a zone, then the given url content will be played on all devices that are members of the zone.

This method calls the play_info SoundTouch API service for the notification. There are models of SoundTouch speakers that do not support notifications. Per the SoundTouch WebServices API reference: audio Notifications are only available for SoundTouch 10, SoundTouch 20 Series III, and SoundTouch 30 Series III. Attempting to send an Audio Notification to an incompatible device will return a 403 Forbidden error.

play_info supports the following file formats and bit rates:

  • MP3: 8 kbit/s ~ 320 kbit/s
  • AAC: 24 kbit/s ~ 128 kbit/s
  • HE-AAC: 48 kbit/s ~ 64 kbit/s
  • WMA: 8 kbit/s ~ 329 kbit/s
  • Vorbis: 32 kbit/S ~ 500 kbit/s
  • FLAC: VBR: 0bit/s ~ 1.4 Mbit/s, up to CD quality (2 channels / 48 kHz / 16 bit)
  • ALAC: 300 kbit/s ~ 5 Mbit/s, HD (2 channels / 96 kHz / 32 bit)

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n(before): %s" % (nowPlaying.ToString()))

    # play the given https url at the current volume level.
    print("\nPlaying HTTPS URL content from the web ...")
    client.PlayUrl("https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_1MB_MP3.mp3",
                   "FreeTestData.com",
                   "MP3 Test Data",
                   "Free_Test_Data_1MB_MP3",
                   volumeLevel=0)

    # play the given http url at the current volume level.
    print("\nPlaying HTTP URL content from the web ...")
    client.PlayUrl("http://www.hyperion-records.co.uk/audiotest/14%20Clementi%20Piano%20Sonata%20in%20D%20major,%20Op%2025%20No%206%20-%20Movement%202%20Un%20poco%20andante.MP3",
                   "Clementi",
                   "Movements Album",
                   "Piano Sonata in D major",
                   volumeLevel=0)

    # play the given url, retrieving metadata (artist,album,track) from the url content.
    print("\nPlaying HTTP URL content from Home Assistant ...")
    client.PlayUrl("http://homeassistant.local:8123/media/local/06%20Flawless.mp3?authSig=xxxx",
                   getMetaDataFromUrlFile=True,
                   volumeLevel=0)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n(after):  %s" % (nowPlaying.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def Power(self) -> None:

Toggle power on / off.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # toggle power on / off of the device.
    client.Power()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PowerOff(self, refresh: bool = True) -> None:

Set power off, if the device is currently powered on and not in standby mode. This will place the device into STANDBY power mode.

Arguments:
  • refresh (bool): True to check the real-time status of the device; otherwise, False to check the cached status of the device.
    Default = True.

This will first issue a GetNowPlayingStatus() method call to query the current status of the device. If the refresh argument is True, then the status is refreshed with real-time data; otherwise the cached status is used.

If the nowPlaying source is not "STANDBY", then the POWER key will be sent to power off the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # power off (standby) the device.
    client.PowerOff()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PowerOn(self, refresh: bool = True) -> None:

Set power on, if the device is currently in standby mode.

Arguments:
  • refresh (bool): True to check the real-time status of the device; otherwise, False to check the cached status of the device.
    Default = True.

This will first issue a GetNowPlayingStatus() method call to query the current status of the device. If the refresh argument is True, then the status is refreshed with real-time data; otherwise the cached status is used.

If the nowPlaying source is "STANDBY", then the POWER key will be sent to power on the device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # power on the device.
    client.PowerOn()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PowerStandby(self) -> None:

Set power to standby, if the device is currently powered on.

This method does not update a configuration, as there is no object to configure - it simply places the device in STANDBY mode.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # power standby (off) the device.
    client.PowerStandby()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(after):  '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def PowerStandbyLowPower(self) -> None:

Set power to low-power standby, if the device is currently powered on.

This method does not update a configuration, as there is no object to configure - it simply places the device in low-power standby mode.

Upon completion, the device will no longer respond to remote control commands nor to webservices api commands, as it is low-power mode. You must physically hold down the power button on the device to turn it back on.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("(before): '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

    # power standby (low-power) the device.
    client.PowerStandbyLowPower()

    # note that no web-services api commands can be issued after this until the
    # device is physically powered back on by holding down the power button.

except Exception as ex:

    print("** Exception: %s" % str(ex))

Makes a POST request to apply a new value for the given node.

Use this method when setting some configuration related data. All standard operations where a POST request is necessary are implemented by this class.

Arguments:
  • uri (SoundTouchUri): The node where the requested value is stored.
  • body (SoundTouchModelRequest | str): The request body xml, or a class that inherits from SoundTouchModelRequest that implements the ToXmlRequestBody method.
  • returnClassType (type): The configuration class type (e.g. NavigateResponse, etc) to return. Default is None; do not return a class type.

Returns: If the returnClassType argument is specified, then a new instance of the class type is returned with the parsed message response.

Otherwise, a `SoundTouchMessage` object storing the request uri, a payload that 
has been sent (optional), and the response as an `xml.etree.ElementTree.Element`.
Raises:
  • SoundTouchError: When errors should not be ignored on this client, they will raise a SoundTouchError exception with all information related to that error.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *
from xml.etree.ElementTree import Element
from xml.etree import ElementTree

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # update configuration for specified node.
    msg:SoundTouchMessage = client.Put(SoundTouchNodes.volume, '<volume>10</volume>')

    if msg != None:
        ElementTree.indent(msg.Response)  # for pretty printing
        responseEncoded = ElementTree.tostring(msg.Response, encoding="unicode")
        print("Put Response Message:\n%s" %  responseEncoded)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RefreshConfiguration( self, uri: bosesoundtouchapi.uri.soundtouchuri.SoundTouchUri, classType) -> object:

Refreshes the cached configuration for the given URI.

Arguments:
  • uri (SoundTouchUri): The configuration uri key.
  • classType (type): The configuration class type (e.g. Balance, Volume, etc) to return.
  • refresh (bool): True to refresh the property with real-time information from the device; otherwise, False to just return the cached value.
Returns:

A configuration instance of the provided classType argument.

This method will call the Get() method to refresh the configuration with real-time information from the device, and store the results in the cache.

def RemoveAllPresets(self) -> bosesoundtouchapi.models.presetlist.PresetList:

Removes all presets from the device's list of presets.

Returns:

A PresetList object that contains the updated preset list configuration of the device.

Raises:
  • Exception: If the command fails for any reason.

A GetPresetList() method call is made to retrieve the current list of presets. The returned list of presets are deleted one by one.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # remove all presets.
    presetList:PresetList = client.RemoveAllPresets()
    print(presetList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RemoveFavorite(self) -> None:

Removes the currently playing media from the device favorites.

This will first make a call to GetNowPlayingStatus() method to ensure favorites are enabled for the now playing media. If not enabled, then the request is ignored and no exception is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time 

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # are favorite functions allowed for currently playing media?
    if nowPlaying.IsFavoriteEnabled:

        # remove the currently playing media from the device favorites.
        client.RemoveFavorite()

        # give the device time to process the change.
        time.sleep(1)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    else:

        print("\nFavorites not enabled for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RemoveGroupStereoPair(self) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Removes an existing left / right stereo pair speaker group.

Arguments:
  • group (Group): Speaker group configuration object that defines the group.
Raises:
  • SoundTouchError: If SoundTouch WebService call fails for any reason.

The device that issues the call to this method has to be the master of the group, or the service will fail.

The device will generate a groupUpdated websocket event, which contains the updated Group configuration.

The ST-10 is the only SoundTouch product that supports stereo pair groups.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current group configuration status.
    groupBefore:Group = client.GetGroupStereoPairStatus()
    print("\nGroup Status Before:\n%s" % groupBefore.ToString(True))

    # remove existing group configuration on the device.
    print("\nRemoving Group: '%s'" % groupBefore.Name)
    client.RemoveGroupStereoPair()

    # get current group configuration status.
    groupBefore:Group = client.GetGroupStereoPairStatus()
    print("\nGroup Status After:\n%s" % groupBefore.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RemoveMusicServiceAccount( self, source: str, displayName: str, userAccount: str, password: str = None) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Removes an existing music service account from the sources list.

Arguments:
  • source (str): Account source value (e.g. "STORED_MUSIC", "SPOTIFY", "AMAZON", etc).
  • displayName (str): Account display name that appears in UI's.
  • userAccount (str): User account value used to authenticate to the service.
  • password (str): Password value used to authenticate to the service.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time 

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get list of defined sources.
    sourceList:SourceList = client.GetSourceList()
    print("\nSource list before the change:\n%s" % sourceList.ToString(True))

    # get list of upnp media services detected by the device.
    mediaServerList:MediaServerList = client.GetMediaServerList()
    print("\nUPnP Media Server list before the change:\n%s" % mediaServerList.ToString(True))

    # remove all music service account sources for upnp media servers.
    print("\n\nRemoving all music service 'STORED_MUSIC' account sources ...")
    mediaServer:MediaServer
    for mediaServer in mediaServerList:
        sourceAccount:str = "%s%s" % (mediaServer.ServerId, "/0")
        sourceItem:SourceItem
        for sourceItem in sourceList:
            if sourceItem.SourceAccount == mediaServer.ServerId:
                print("- Removing source: '%s' (%s)" % (mediaServer.FriendlyName, sourceItem.SourceAccount))
                client.RemoveMusicServiceAccount(sourceItem.Source, sourceItem.FriendlyName, sourceItem.SourceAccount, None)
                break
            elif sourceItem.SourceAccount == sourceAccount:
                print("- Removing source: '%s' (%s)" % (mediaServer.FriendlyName, sourceAccount))
                client.RemoveMusicServiceAccount(sourceItem.Source, sourceItem.FriendlyName, sourceAccount, None)
                break

    # get real-time configuration from the device.
    sourceList:SourceList = client.GetSourceList()
    print("\nSource list after the remove:\n%s" % sourceList.ToString(True))

    # add all music service account sources for upnp media servers.
    print("\nAdding all UPnP media servers as 'STORED_MUSIC' account sources ...")
    mediaServer:MediaServer
    for mediaServer in mediaServerList:
        sourceAccount:str = "%s%s" % (mediaServer.ServerId, "/0")
        print("- Adding source: '%s' (%s)" % (mediaServer.FriendlyName, sourceAccount))
        client.SetMusicServiceAccount("STORED_MUSIC", mediaServer.FriendlyName, sourceAccount, None)

    # get list of defined sources.
    sourceList:SourceList = client.GetSourceList()
    print("\nSource list after the set:\n%s" % sourceList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Removes a station from a music service (e.g. PANDORA, etc) collection of previously stored stations.

Arguments:
  • removeStation (RemoveStation): Criteria used to remove the music service station.
Returns:

A SoundTouchMessage object that contains the response.

Raises:
  • SoundTouchError: If the device is not capable of supporting removeStation functions, as determined by a query to the cached supportedURLs web-services api.

Playing will be stopped and the NowPlaying status will be updated with source="INVALID_SOURCE" if the station being removed is currently playing; otherwise, currently playing content is not changed.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get my collection of PANDORA music service stations.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId")
    resultsBefore:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\n%s Music Service Stations before:\n%s" % (criteria.Source, resultsBefore.ToString(True)))

    # remove station from my collection of PANDORA music service stations.
    removeStation:RemoveStation = RemoveStation(SoundTouchSources.PANDORA, "YourMusicServiceUserId", "98000573042799134", "Zach Williams & Essential Worship")
    print("\nRemoving Station: %s" % removeStation.ToString())
    client.RemoveMusicServiceStation(removeStation)

    # commented out in case you really don't want to do this ...
    # remove all stations from my collection of PANDORA music service stations.
    # item:NavigateItem
    # for item in resultsBefore.Items:
    #     removeStation:RemoveStation = RemoveStation(contentItem=item.ContentItem)
    #     print("\nRemoving Station: %s" % removeStation.ToString())
    #     client.RemoveMusicServiceStation(removeStation)

    # get my collection of PANDORA music service stations.
    criteria:Navigate = Navigate(SoundTouchSources.PANDORA, "YourMusicServiceUserId")
    resultsAfter:NavigateResponse = client.GetMusicServiceStations(criteria)
    print("\n%s Music Service Stations after:\n%s" % (criteria.Source, resultsAfter.ToString(True)))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RemovePreset(self, presetId: int) -> bosesoundtouchapi.models.presetlist.PresetList:

Removes the specified Preset id from the device's list of presets.

Arguments:
  • presetId (int): The preset id to remove; valid values are 1 thru 6.
Returns:

A PresetList object that contains the updated preset list configuration of the device.

Raises:
  • Exception: If the command fails for any reason.

The preset with the specified id is removed.
No exception is raised if the preset id does not exist.

Presets and favorites in the SoundTouch app are not reordered once the preset is removed; it simply creates an open / empty slot in the list.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # remove preset #4.
    presetList:PresetList = client.RemovePreset(4)
    print(presetList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RemoveZone( self, delay: int = 1) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Removes the given zone.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER removing zone members. This delay will give the device time to process the change before another command is accepted.
    Default is 1; value range is 0 - 10.
Raises:
  • SoundTouchError: Master zone status could not be retrieved.
    Master zone does not exist; zone members cannot be removed.

This method retrieves the current master zone status, and issues a call to RemoveZoneMembers to remove all members from the zone.

Note that the master zone itself is also removed; you will need to reissue a call to the CreateZone() method to re-create the master zone.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current zone configuration status.
    zoneBefore:Zone = client.GetZoneStatus()
    print("\nCurrent Zone Status:\n%s" % zoneBefore.ToString(True))

    # if zone not active, then create one so that we have something to remove.
    if len(zoneBefore.Members) == 0:

        print("Creating a new master zone so we have a zone to remove ...")

        # build list of zone members to remove.
        zoneMembers:list = []
        zoneMembers.append(ZoneMember("192.168.1.80", "E8EB11B9B723"))

        # initialize the new master zone configuration.
        masterZone:Zone = Zone(client.Device.DeviceId, client.Device.Host, True) # <- master
        member:ZoneMember
        for member in zoneMembers:
            masterZone.AddMember(member)                                         # <- member

        # create a new master zone configuration on the device.
        client.CreateZone(masterZone)

        # get current zone configuration status.
        zoneBefore:Zone = client.GetZoneStatus()
        print("\nZone Status Before:\n%s" % zoneBefore.ToString(True))

    # remove the master zone configuration from the device.
    client.RemoveZone()

    # get current zone configuration status.
    zoneAfter:Zone = client.GetZoneStatus()
    print("\nZone Status After:\n%s" % zoneAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RemoveZoneMembers( self, members: list, delay: int = 3) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Removes the given zone members from the device's zone.

Arguments:
  • members (list): A list of ZoneMember objects to remove from the master zone.
  • delay (int): Time delay (in seconds) to wait AFTER removing zone members. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.
Raises:
  • SoundTouchError: Master zone status could not be retrieved.
    Master zone does not exist; zone members cannot be removed.
    Members argument was not supplied, or has no members.
    Members argument contained a list item that is not of type ZoneMember.

This method must be called by the master device of an existing zone; only the master can remove zone members.

Note that the master zone itself is also removed if there are no zone members left after the remove request is complete. In this case, you will need to reissue a call to the CreateZone() method to re-create the master zone.

The SoundTouch device does not return errors if a zone member device id does not exist; it simply ignores the invalid member entry and moves on to the next.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # build list of zone members to remove.
    zoneMembers:list = []
    zoneMembers.append(ZoneMember("192.168.1.80", "E8EB11B9B723"))

    # get current zone configuration status.
    zoneBefore:Zone = client.GetZoneStatus()
    print("\nCurrent Zone Status:\n%s" % zoneBefore.ToString(True))

    # if zone not active, then create one so that we have something to remove.
    if len(zoneBefore.Members) == 0:

        print("Creating a new master zone so we have a zone member to remove ...")

        # initialize the new master zone configuration.
        masterZone:Zone = Zone(client.Device.DeviceId, client.Device.Host, True) # <- master
        member:ZoneMember
        for member in zoneMembers:
            masterZone.AddMember(member)                                         # <- member

        # create a new master zone configuration on the device.
        client.CreateZone(masterZone)

        # get current zone configuration status.
        zoneBefore:Zone = client.GetZoneStatus()
        print("\nZone Status Before:\n%s" % zoneBefore.ToString(True))

    # remove zone members from the master zone configuration on the device.
    client.RemoveZoneMembers(zoneMembers)

    # get current zone configuration status.
    zoneAfter:Zone = client.GetZoneStatus()
    print("\nZone Status After:\n%s" % zoneAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def RestoreSnapshot(self, delay: int = 5) -> None:

Restores selected portions of the configuration from a snapshot that was previously taken with the StoreSnapshot method.

Arguments:
  • delay (int): Time delay (in seconds) to wait for the playing content to change.
    Default is 5 seconds.

The following settings will be restored from the snapshot dictionary by default:

  • SoundTouchNodes.nowPlaying.Path - playing content.
  • SoundTouchNodes.volume.Path - volume level and mute status.

No restore actions will be taken if snapshot settings do not exist.

You can restore your own custom settings from the snapshot dictionary; note that these custom settings are NOT restored by default.

You may remove default items from the snapshot dictionary prior to calling the RestoreSnapshot method. Let's say you did not want to restore the volume level - simply remove the volume item from the snapshot dictionary. See the sample code below for an example.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current settings that will be restored by the snapshot.
    print("** Settings before StoreSnapshot ... **")
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("Now Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))
    volume:Volume = client.GetVolume(True)
    print("Volume     : %s" % (volume.ToString()))

    # store current settings to snapshot.
    print("\n** Storing Snapshot ... **")
    client.StoreSnapshot()
    print("\n** Snapshot stored **\n")

    # select a different source.
    print("Changing Source ...")
    client.SelectSource(SoundTouchSources.BLUETOOTH)

    # change the volume level.
    print("Changing Volume to 30 ...")
    client.SetVolumeLevel(30)

    # mute the device.
    print("Changing Mute to On ...")
    client.MuteOn()

    # get current settings before the snapshot restore.
    print("\n** Settings before RestoreSnapshot ... **")
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("Now Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))
    volume:Volume = client.GetVolume(True)
    print("Volume     : %s" % (volume.ToString()))

    # if you don't want to restore a configuration, then simply delete 
    # it from the snapshot dictionary, like so:
    # if SoundTouchNodes.volume.Path in client.SnapshotSettings:
    #     client.SnapshotSettings.pop(SoundTouchNodes.volume.Path)

    # restore settings from snapshot.
    print("\n** Restoring Snapshot ... **")
    client.RestoreSnapshot()

    # get current settings after the snapshot restore.
    print("\n** Settings after RestoreSnapshot (should match settings before StoreSnapshot) ... **")
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("Now Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))
    volume:Volume = client.GetVolume(True)
    print("Volume     : %s" % (volume.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SearchMusicLibrary( self, search: bosesoundtouchapi.models.search.Search) -> bosesoundtouchapi.models.searchresponse.SearchResponse:

Searches a specified music library container (e.g. STORED_MUSIC, etc).

Arguments:
  • search (Navigate): Criteria used to search the music library.
Returns:

A SearchResponse object that contains the response.

Raises:
  • SoundTouchError: If the device is not capable of supporting search functions, as determined by a query to the cached supportedURLs web-services api.

Use the GetSourceList method to get the source and sourceAccount values for the specific NAS Music Library you wish to navigate.

A returned SearchResponse item can be used to play the item's media content by passing its ContentItem value to the PlayContentItem method.

You must pay close attention to the filter attribute on the SearchTerm node, as the SoundTouch webservices API is very picky on what filter types are allowed for a container.

The StartItem node is required; otherwise, the search fails.

Music library containers can found using the GetMusicLibraryItems method. Use a returned NavigateResponse item's ContentItem node in the request.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # the following shows how to traverse the structure of a NAS Music Library.
    # in this example, my NAS Music Library has the following containers defined:
    # - Root container
    # -- Music
    # ---- Albums
    # ------ Welcome to the New
    # ------ ... and more (albums from other artists)
    # ---- ... and more (Album Artists, All Artists, All Music, Composers, Genre, etc)
    # -- ... and more (Pictures, PlayLists, Videos)

    # set NAS library source to access.
    nasSource:str = SoundTouchSources.STORED_MUSIC.value
    nasSourceAccount:str = "d09708a1-5953-44bc-a413-7d516e04b819/0"
    navItem:NavigateItem = None

    # various NAS Library containers in my environment.
    containerAlbumArtists:NavigateItem = NavigateItem(nasSource, nasSourceAccount, "Album Artists", "dir", location="107")
    containerAlbums:NavigateItem = NavigateItem(nasSource, nasSourceAccount, "Albums", "dir", location="7")
    containerAllArtists:NavigateItem = NavigateItem(nasSource, nasSourceAccount, "All Artists", "dir", location="6")
    containerAllMusic:NavigateItem = NavigateItem(nasSource, nasSourceAccount, "All Music", "dir", location="4")
    containerMusicPlaylists:NavigateItem = NavigateItem(nasSource, nasSourceAccount, "Music Playlists", "dir", location="F")

    # search NAS library "Root \ Music \ Music Playlists" for track name.
    search:Search = Search(nasSource, nasSourceAccount, SearchTerm("baby", SearchFilterTypes.Track), containerItem=containerMusicPlaylists)
    print("\nSearching Container: '%s' ..." % search.ContainerTitle)
    results:SearchResponse = client.SearchMusicLibrary(search)
    for navItem in results:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # at this point, you can play any track in the returned results, like so:
    #client.PlayContentItem(results.Items[0].ContentItem)

    # search NAS library "Root \ Music \ All Music" for track name.
    search:Search = Search(nasSource, nasSourceAccount, SearchTerm("christmas", SearchFilterTypes.Track), containerItem=containerAllMusic)
    print("\nSearching Container: '%s' ..." % search.ContainerTitle)
    results:SearchResponse = client.SearchMusicLibrary(search)
    for navItem in results:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # search NAS library "Root \ Music \ Album Artists" for artist name.
    search:Search = Search(nasSource, nasSourceAccount, SearchTerm("MercyMe", SearchFilterTypes.Artist), containerItem=containerAllArtists)
    print("\nSearching Container: '%s' ..." % search.ContainerTitle)
    results:SearchResponse = client.SearchMusicLibrary(search)
    for navItem in results:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # search NAS library "Root \ Music \ Album Artists" for album artist name.
    search:Search = Search(nasSource, nasSourceAccount, SearchTerm("MercyMe", SearchFilterTypes.Artist), containerItem=containerAlbumArtists)
    print("\nSearching Container: '%s' ..." % search.ContainerTitle)
    results:SearchResponse = client.SearchMusicLibrary(search)
    for navItem in results:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # search NAS library "Root \ Music \ Albums" for album name.
    search:Search = Search(nasSource, nasSourceAccount, SearchTerm("Welcome to the New", SearchFilterTypes.Album), containerItem=containerAlbums)
    print("\nSearching Container: '%s' ..." % search.ContainerTitle)
    results:SearchResponse = client.SearchMusicLibrary(search)
    for navItem in results:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

    # search NAS library "Root \ Music \ Albums" for album name.
    search:Search = Search(nasSource, nasSourceAccount, SearchTerm("christmas", SearchFilterTypes.Album), containerItem=containerAlbums)
    print("\nSearching Container: '%s' ..." % search.ContainerTitle)
    results:SearchResponse = client.SearchMusicLibrary(search)
    for navItem in results:
        print("- %s (%s)" % (navItem.Name, navItem.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Searches a music service (e.g. PANDORA, etc) for stations that can be added to a users collection of stations.

Arguments:
  • searchStation (SearchStation): Criteria used to search a music service for available stations.
Returns:

A SoundTouchMessage object that contains the response.

Raises:
  • SoundTouchError: If the device is not capable of supporting searchStation functions, as determined by a query to the cached supportedURLs web-services api.

The AddMusicServiceStation method can be used to add a result item (song or artist) from the results of this method.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # search PANDORA music service stations for specified criteria.
    searchStation:SearchStation = SearchStation(SoundTouchSources.PANDORA, "YourMusicServiceUserId", "Zach Williams")
    print("\nSearching %s Music Service : %s" % (searchStation.Source, searchStation.ToString()))
    results:SearchStationResults = client.SearchMusicServiceStations(searchStation)
    print("\n%s Music Service Stations results:\n%s" % (results.Source, results.ToString(True)))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Selects the given ContentItem.

Arguments:
  • item (ContentItem): Content item to select.
  • delay (int): Time delay (in seconds) to wait AFTER selecting the content item.
    This delay will give the device time to process the change before another command is accepted.
    Default is 5; value range is 0 - 10.

Note that playing of "https://" content is not supported by SoundTouch devices.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlayingBefore:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Current Now Playing Status:\n%s" % nowPlayingBefore.ToString())

    # create various content items to play.
    contentRadio01:ContentItem = ContentItem("TUNEIN","stationurl","/v1/playback/station/s249983","",True,"Christian Hits")
    contentRadio02:ContentItem = ContentItem("TUNEIN","stationurl","/v1/playback/station/s309605","",True,"K-LOVE 90s")

    # ensure the now playing changes.
    selection:ContentItem = contentRadio01
    if nowPlayingBefore.ContentItem != None:
        if nowPlayingBefore.ContentItem.Location == contentRadio01.Location:
            selection = contentRadio02

    # selects the specified content item.
    print("\n** Playing content item: %s - %s ..." % (selection.Name, selection.Location))
    client.SelectContentItem(selection)

    # create various content items to play.
    selections:list = []
    selections.append(ContentItem("TUNEIN","stationurl","/v1/playback/station/s249983",None,True,"Christian Hits"))
    selections.append(ContentItem("UPNP",None,"http://192.168.1.186:8123/api/tts_proxy/c96b99f3a949febd2a1f680e3b6dc4f01eb67e68_en_-_google_translate.mp3","UPnPUserName",True))
    selections.append(ContentItem("LOCAL_INTERNET_RADIO","stationurl","https://content.api.bose.io/core02/svc-bmx-adapter-orion/prod/orion/station?data=eyJuYW1lIjoiSm1uIDgwOTYiLCJpbWFnZVVybCI6IiIsInN0cmVhbVVybCI6Imh0dHA6Ly9qbThuLi5jb20vODA5Ni9zdHJlYW0ifQ%3D%3D",None,True,"Jmn 8096"))
    selections.append(ContentItem("TUNEIN","stationurl","/v1/playback/station/s309605",None,True,"K-LOVE 90s"))

    # play them all
    selection:ContentItem
    for selection in selections:
        print("\n** Playing content item: %s - %s ..." % (selection.Name, selection.Location))
        client.SelectContentItem(selection, 10)

    print("\n** Restoring original source ...")

    # play original source (if one was selected).
    if nowPlayingBefore.ContentItem.Source != "STANDBY":
        client.SelectContentItem(nowPlayingBefore.ContentItem)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Updated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectLastSoundTouchSource( self, delay: int = 3) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Selects the last SoundTouch source that was selected.

Arguments:
  • delay (int): time delay (in seconds) to wait AFTER selecting the source. This delay will give the SoundTouch device time to process the change before another command is accepted.
    Default is 3 seconds, and value range is 0 - 10.
Returns:

A SoundTouchMessage response that indicates success or failure of the command.

Raises:
  • SoundTouchError: If the device is not capable of supporting selectLastSoundTouchSource functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlayingBefore:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Current Now Playing Status:\n%s" % nowPlayingBefore.ToString())

    # select last soundtouch source.
    client.SelectLastSoundTouchSource()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Updated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectLastSource( self, delay: int = 3) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Selects the last source that was selected.

Arguments:
  • delay (int): time delay (in seconds) to wait AFTER selecting the source. This delay will give the SoundTouch device time to process the change before another command is accepted.
    Default is 3 seconds, and value range is 0 - 10.
Returns:

A SoundTouchMessage response that indicates success or failure of the command.

Raises:
  • SoundTouchError: If the device is not capable of supporting selectLastSource functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlayingBefore:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Current Now Playing Status:\n%s" % nowPlayingBefore.ToString())

    # select last source.
    client.SelectLastSource()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Updated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectLastWifiSource( self, delay: int = 3) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Selects the last wifi source that was selected.

Arguments:
  • delay (int): time delay (in seconds) to wait AFTER selecting the source. This delay will give the SoundTouch device time to process the change before another command is accepted.
    Default is 3 seconds, and value range is 0 - 10.
Returns:

A SoundTouchMessage response that indicates success or failure of the command.

Raises:
  • SoundTouchError: If the device is not capable of supporting selectLastWiFiSource functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlayingBefore:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Current Now Playing Status:\n%s" % nowPlayingBefore.ToString())

    # select last wifi source.
    client.SelectLastWifiSource()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Updated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectLocalSource( self, delay: int = 3) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Selects the LOCAL source; for some SoundTouch devices, this is the only way that the LOCAL source can be selected.

Arguments:
  • delay (int): time delay (in seconds) to wait AFTER selecting the source. This delay will give the SoundTouch device time to process the change before another command is accepted.
    Default is 3 seconds, and value range is 0 - 10.
Returns:

A SoundTouchMessage response that indicates success or failure of the command.

Raises:
  • SoundTouchError: If the device is not capable of supporting selectLocalSource functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlayingBefore:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Current Now Playing Status:\n%s" % nowPlayingBefore.ToString())

    # select local source.
    client.SelectLocalSource()

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Updated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

Selects the given preset.

Arguments:
  • item (Preset): Preset item to select.
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 5; value range is 0 - 10.
Raises:
  • SoundTouchError: Preset argument was not supplied.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    print("Getting list of presets ...")

    # get list of defined presets.
    presetList:PresetList = client.GetPresetList()
    print(presetList.ToString(True))

    preset:Preset
    for preset in presetList:

        print("\nSelecting Preset: '%s' - %s" % (preset.Name, preset.Location))

        # select a preset, and delay 10 seconds after for the device to process the change.
        client.SelectPreset(preset, 10)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("\nNow Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectPreset1(self, delay: int = 3) -> None:

Selects pre-defined preset number 1 on the device.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.

This method does nothing if there is no preset at the specified preset index.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # select the preset, and delay 3 seconds after for the device to process the change.
    client.SelectPreset1(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectPreset2(self, delay: int = 3) -> None:

Selects pre-defined preset number 2 on the device.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.

This method does nothing if there is no preset at the specified preset index.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # select the preset, and delay 3 seconds after for the device to process the change.
    client.SelectPreset2(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectPreset3(self, delay: int = 3) -> None:

Selects pre-defined preset number 3 on the device.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.

This method does nothing if there is no preset at the specified preset index.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # select the preset, and delay 3 seconds after for the device to process the change.
    client.SelectPreset3(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectPreset4(self, delay: int = 3) -> None:

Selects pre-defined preset number 4 on the device.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.

This method does nothing if there is no preset at the specified preset index.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # select the preset, and delay 3 seconds after for the device to process the change.
    client.SelectPreset4(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectPreset5(self, delay: int = 3) -> None:

Selects pre-defined preset number 5 on the device.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.

This method does nothing if there is no preset at the specified preset index.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # select the preset, and delay 3 seconds after for the device to process the change.
    client.SelectPreset5(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectPreset6(self, delay: int = 3) -> None:

Selects pre-defined preset number 6 on the device.

Arguments:
  • delay (int): Time delay (in seconds) to wait AFTER selecting the preset. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.

This method does nothing if there is no preset at the specified preset index.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # select the preset, and delay 3 seconds after for the device to process the change.
    client.SelectPreset6(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

Selects the given recent.

Arguments:
  • item (Recent): Recent item to select.
  • delay (int): Time delay (in seconds) to wait AFTER selecting the recent. This delay will give the device time to process the change before another command is accepted.
    Default is 5; value range is 0 - 10.
Raises:
  • SoundTouchError: Recent argument was not supplied.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    print("Getting list of recents ...")

    # get list of defined recents.
    recents:RecentList = client.GetRecentList()
    print(recents.ToString(True))

    # process list.
    recent:Recent = None
    for i, recent in list(enumerate(recents)):

        print("\nSelecting Recent: '%s' - %s" % (recent.Name, recent.Location))

        # select a recent, and delay 10 seconds after for the device to process the change.
        client.SelectRecent(recent, 10)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("\nNow Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))

        # only process a few of the recent entries, as there could be a lot.
        if i >= 2:
            break

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SelectSource( self, source: bosesoundtouchapi.soundtouchsources.SoundTouchSources, sourceAccount: str = None, delay: int = 3) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Selects a new input source.

Arguments:
  • source (SoundTouchSources | str): Input source value; this can either be a SoundTouchSources enum value or a string. If specifying a string value, then it should be in upper-case.
  • sourceAccount (str): Source account value; some sources require one when changing the input source (e.g. "AUX").
  • delay (int): time delay (in seconds) to wait AFTER selecting the source. This delay will give the SoundTouch device time to process the change before another command is accepted. default is 3 seconds, and value range is 0 - 10.
Returns:

A SoundTouchMessage response that indicates success or failure of the command.

Raises:
  • SoundTouchError: Source argument was not supplied.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlayingBefore:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Current Now Playing Status:\n%s" % nowPlayingBefore.ToString())

    # get list of source items.
    sources:SourceList = client.GetSourceList()

    print("\n** Sources supported by the device:\n%s" % sources.ToString(True))
    print("\n** Selecting Sources one-by-one ...")

    # select each source.
    sourceItem:SourceItem
    for sourceItem in sources:

        # trace.
        print("- Source='%s', SourceAccount='%s' ..." % (sourceItem.Source, sourceItem.SourceAccount))

        # select an input source.
        msg:SoundTouchMessage = client.SelectSource(sourceItem.Source, sourceItem.SourceAccount)

    print("\n** Restoring original source ...")

    # play original source (if one was selected).
    if nowPlayingBefore.ContentItem.Source != "STANDBY":
        client.SelectContentItem(nowPlayingBefore.ContentItem)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\n** Updated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

Sets the current audio dsp controls configuration of the device.

Arguments:
  • controls (AudioDspControls): A AudioDspControls object that contains audio dsp control values to set.
Raises:
  • SoundTouchError: If the device is not capable of supporting audiodspcontrols functions, as determined by a query to the cached supportedURLs web-services api.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.80")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current audio dsp controls.
    # note that not all devices support retrieval of this information.
    cfgBefore:AudioDspControls = None
    cfgBefore = client.GetAudioDspControls(True)
    print("\nCurrent audio dsp controls: \n%s" % (cfgBefore.ToString()))
    print("Supported Audio Modes array: %s" % (cfgBefore.ToSupportedAudioModesArray()))

    # create new audio dsp controls object.
    cfgUpdate:AudioDspControls = AudioDspControls()
    cfgUpdate.VideoSyncAudioDelay = cfgBefore.VideoSyncAudioDelay

    # for testing purposes, toggle the audio mode.
    # if the mode is currently "AUDIO_MODE_NORMAL" then we will use "AUDIO_MODE_DIALOG", or vice versa.
    cfgUpdate.AudioMode = AudioDspAudioModes.Normal
    if cfgUpdate.AudioMode == cfgBefore.AudioMode:
        cfgUpdate.AudioMode = AudioDspAudioModes.Dialog
    print("\nSetting audio dsp controls AudioMode to '%s' (from '%s') ..." % (cfgUpdate.AudioMode, cfgBefore.AudioMode))

    # set audio dsp controls to specific audio mode.
    client.SetAudioDspControls(cfgUpdate)

    # get current audio dsp controls.
    cfgAfter:AudioDspControls = client.GetAudioDspControls(True)
    print("\nChanged audio dsp controls: \n%s" % (cfgAfter.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

finally:

    if cfgBefore is not None:

        # restore audio dsp controls to original values.
        client.SetAudioDspControls(cfgBefore)            

        # get current audio dsp controls.
        cfgAfter:AudioProductLevelControls = client.GetAudioDspControls(True)
        print("\nRestored audio dsp controls: \n%s" % (cfgAfter.ToString()))

def SetAudioProductLevelControls( self, controls: bosesoundtouchapi.models.audioproductlevelcontrols.AudioProductLevelControls) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Sets the current audio product tone controls configuration of the device.

Arguments:
  • controls (AudioProductLevelControls): A AudioProductLevelControls object that contains audio product tone control values to set.
Raises:
  • SoundTouchError: If the device is not capable of supporting audioproductlevelcontrols functions, as determined by a query to the cached supportedURLs web-services api.
    If the controls argument is None, or not of type AudioProductLevelControls.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.80")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current audio product level controls.
    # note that not all devices support retrieval of this information.
    cfgBefore:AudioProductLevelControls = None
    cfgBefore = client.GetAudioProductLevelControls()
    print("\nCurrent audio product level controls: \n%s" % cfgBefore.ToString())

    # create new audio product level controls object.
    cfgUpdate:AudioProductLevelControls = AudioProductLevelControls()

    # for testing purposes, toggle the FrontCenterSpeakerLevel level.  
    # if the level is currently minValue, then we will set to maxValue.
    cfgUpdate.FrontCenterSpeakerLevel.Value = cfgBefore.FrontCenterSpeakerLevel.MinValue
    if cfgUpdate.FrontCenterSpeakerLevel.Value == cfgBefore.FrontCenterSpeakerLevel.Value:
        cfgUpdate.FrontCenterSpeakerLevel.Value = cfgBefore.FrontCenterSpeakerLevel.MaxValue
    print("\nSetting audio product level controls FrontCenterSpeakerLevel to '%s' (from '%s') ..." % (cfgUpdate.FrontCenterSpeakerLevel.Value, cfgBefore.FrontCenterSpeakerLevel.Value))

    # for testing purposes, toggle the RearSurroundSpeakersLevel level.  
    # if the level is currently minValue, then we will set to maxValue.
    cfgUpdate.RearSurroundSpeakersLevel.Value = cfgBefore.RearSurroundSpeakersLevel.MinValue
    if cfgUpdate.RearSurroundSpeakersLevel.Value == cfgBefore.RearSurroundSpeakersLevel.Value:
        cfgUpdate.RearSurroundSpeakersLevel.Value = cfgBefore.RearSurroundSpeakersLevel.MaxValue
    print("Setting audio product level controls RearSurroundSpeakersLevel to '%s' (from '%s') ..." % (cfgUpdate.RearSurroundSpeakersLevel.Value, cfgBefore.RearSurroundSpeakersLevel.Value))

    # update audio product level controls.
    client.SetAudioProductLevelControls(cfgUpdate)

    # get current audio product level controls.
    cfgAfter:AudioProductLevelControls = client.GetAudioProductLevelControls(True)
    print("\nChanged audio product level controls: \n%s" % (cfgAfter.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

finally:

    if cfgBefore is not None:

        # restore audio product level controls to original values.
        client.SetAudioProductLevelControls(cfgBefore)            

        # get current audio product level controls.
        cfgAfter:AudioProductLevelControls = client.GetAudioProductLevelControls(True)
        print("\nRestored audio product level controls: \n%s" % (cfgAfter.ToString()))

Sets the current audio product tone controls configuration of the device.

Arguments:
  • controls (AudioProductToneControls): A AudioProductToneControls object that contains audio product tone control values to set.
Raises:
  • SoundTouchError: If the device is not capable of supporting audioproducttonecontrols functions, as determined by a query to the cached supportedURLs web-services api.
    If the controls argument is None, or not of type AudioProductToneControls.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.80")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current audio product tone controls.
    # note that not all devices support retrieval of this information.
    cfgBefore:AudioProductToneControls = None
    cfgBefore = client.GetAudioProductToneControls()
    print("\nCurrent audio product tone controls: \n%s" % cfgBefore.ToString())

    # create new audio product tone controls object.
    cfgUpdate:AudioProductToneControls = AudioProductToneControls()

    # for testing purposes, toggle the Bass level.  
    # if the level is currently minValue, then we will set to maxValue.
    cfgUpdate.Bass.Value = cfgBefore.Bass.MinValue
    if cfgUpdate.Bass.Value == cfgBefore.Bass.Value:
        cfgUpdate.Bass.Value = cfgBefore.Bass.MaxValue
    print("\nSetting audio product tone controls Bass Level to '%s' (from '%s') ..." % (cfgUpdate.Bass.Value, cfgBefore.Bass.Value))

    # for testing purposes, toggle the Treble level.  
    # if the level is currently minValue, then we will set to maxValue.
    cfgUpdate.Treble.Value = cfgBefore.Treble.MinValue
    if cfgUpdate.Treble.Value == cfgBefore.Treble.Value:
        cfgUpdate.Treble.Value = cfgBefore.Treble.MaxValue
    print("Setting audio product tone controls Treble Level to '%s' (from '%s') ..." % (cfgUpdate.Treble.Value, cfgBefore.Treble.Value))

    # update audio product tone controls.
    client.SetAudioProductToneControls(cfgUpdate)

    # get current audio product tone controls.
    cfgAfter:AudioProductToneControls = client.GetAudioProductToneControls(True)
    print("\nChanged audio product tone controls: \n%s" % (cfgAfter.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

finally:

    if cfgBefore is not None:

        # restore audio product tone controls to original values.
        client.SetAudioProductToneControls(cfgBefore)            

        # get current audio product tone controls.
        cfgAfter:AudioProductToneControls = client.GetAudioProductToneControls(True)
        print("\nRestored audio product tone controls: \n%s" % (cfgAfter.ToString()))

def SetBalanceLevel( self, level: int) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Sets the device balance level to the given level.

Arguments:
  • level (int): Balance level to set, usually in the range of -7 (left) to 7 (right).

This method only works if the device is configured as part of a stereo pair.

The argument level range can vary by device; use the GetBalance method to determine if the device has the capability to adjust the balance, as well as the allowable range (minimum, maximum, default) levels.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # This test only works if the device is configured as part of a stereo pair.
    # this example will perform the following steps:
    # - set balance to minimum (left speaker).
    # - set balance to middle (both speakers).
    # - set balance to maximum (right speaker).
    # - restore balance to original value.

    print("Getting balance capability configuration ...")

    # get current balance levels and capabilities.
    balanceBefore:Balance = client.GetBalance(True)
    print("\nCurrent Balance Config: %s" % (balanceBefore.ToString()))

    # does the device have the capability to change the balance level?
    if balanceBefore.IsAvailable:

        # set balance to specific level.
        NEW_LEVEL:int = balanceBefore.Minimum
        print("Setting Balance level to Minimum: %s" % (NEW_LEVEL))
        client.SetBalanceLevel(NEW_LEVEL)

        # get current balance levels.
        balanceAfter:Balance = client.GetBalance(True)
        print("Current Balance Config: %s" % (balanceAfter.ToString()))

        # give the tester time to verify.
        time.sleep(3)

        # set balance to specific level.
        NEW_LEVEL:int = balanceBefore.Default
        print("Setting Balance level to Default: %s" % (NEW_LEVEL))
        client.SetBalanceLevel(NEW_LEVEL)

        # get current balance levels.
        balanceAfter:Balance = client.GetBalance(True)
        print("Current Balance Config: %s" % (balanceAfter.ToString()))

        # give the tester time to verify.
        time.sleep(5)

        # set balance to specific level.
        NEW_LEVEL:int = balanceBefore.Maximum
        print("Setting Balance level to Maximum: %s" % (NEW_LEVEL))
        client.SetBalanceLevel(NEW_LEVEL)

        # get current balance levels.
        balanceAfter:Balance = client.GetBalance(True)
        print("Current Balance Config: %s" % (balanceAfter.ToString()))

        # give the tester time to verify.
        time.sleep(5)

        # restore original level.
        NEW_LEVEL:int = balanceBefore.Actual
        print("Restoring original Balance level to: %s" % (NEW_LEVEL))
        client.SetBalanceLevel(NEW_LEVEL)

        # get current balance levels.
        balanceAfter:Balance = client.GetBalance(True)
        print("Current Balance Config: %s" % (balanceAfter.ToString()))

    else:

        print("\n** Device '%s' does not support changing balance levels!" % device.DeviceName)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SetBassLevel( self, level: int) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Sets the device bass level to the given level.

Arguments:
  • level (int): Bass level to set, usually in the range of -9 (no bass) to 0 (full bass).

The argument level range can vary by device; use the GetBassCapabilities() method to retrieve the allowable range for a device.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    print("Getting bass capability configuration ...")

    # get current bass capabilities.
    bassCapabilities:BassCapabilities = client.GetBassCapabilities()
    print(bassCapabilities.ToString())

    # does the device have the capability to change the bass level?
    if bassCapabilities.IsAvailable:

        # get current bass level.
        bassBefore:Bass = client.GetBass(True)
        print("\nCurrent Bass Levels: %s" % (bassBefore.ToString()))

        # for testing purposes, use a maximum bass level as defined by capabilities.
        # if the bass level is currently at maximum, then we will use a value of minimum.
        newLevel:int = bassCapabilities.Maximum
        if bassBefore.Actual == newLevel:
            newLevel = bassCapabilities.Minimum
        print("\nSetting Bass level to %d (from %s) ..." % (newLevel, bassBefore.Actual))

        # set bass to specific level.
        client.SetBassLevel(newLevel)

        # get current bass level.
        bassAfter:Bass = client.GetBass(True)
        print("\nChanged Bass Levels: %s" % (bassAfter.ToString()))

    else:

        print("Device '%s' does not support changing bass levels!" % device.DeviceName)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SetMusicServiceAccount( self, source: str, displayName: str, userAccount: str, password: str = None) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Adds a music service account to the sources list.

Arguments:
  • source (str): Account source value (e.g. "STORED_MUSIC", "SPOTIFY", "AMAZON", etc).
  • displayName (str): Account display name that appears in UI's.
  • userAccount (str): User account value used to authenticate to the service. This value must exactly match (case-sensitive) the media server id in the MediaServer instance.
  • password (str): Password value used to authenticate to the service.

UPnP media server music service (e.g. "STORED_MUSIC") sources can only be set if the device has detected the UPnP media server. The detected UPnP media servers will appear in the MediaServerList of items obtained using a call to GetMediaServerList method.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time 

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get list of defined sources.
    sourceList:SourceList = client.GetSourceList()
    print("\nSource list before the change:\n%s" % sourceList.ToString(True))

    # set music service account source - Music Library on NAS (STORED_MUSIC).
    # note the userAccount value must match what is defined in the "/listMediaServers" service, with an ending "/0".
    print("\n\nAdding music service source: Music Library on NAS, Account='d09708a1-5953-44bc-a413-123456789012' ...")
    client.SetMusicServiceAccount("STORED_MUSIC", "Music Library on NAS", "d09708a1-5953-44bc-a413-123456789012/0", None)

    # set music service account source - PANDORA.
    print("\n\nAdding music service source: Pandora, Account='yourPandoraUserId' ...")
    client.SetMusicServiceAccount("PANDORA", "Pandora Account", "yourPandoraUserId", "yourPandoraPassword")

    # get list of defined sources.
    sourceList:SourceList = client.GetSourceList()
    print("\nSource list after the set:\n%s" % sourceList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Sets a new device name.

Sample Code

from bosesoundtouchapi import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    print("Name Before: '%s'" % client.Device.DeviceName)

    # set the device name.
    client.SetName('My SoundTouch 10')

    print("Name After:  '%s'" % client.Device.DeviceName)

except Exception as ex:

    print("** Exception: %s" % str(ex))

Sets the current product cec hdmi control configuration of the device.

Arguments:
  • control (ProductCecHdmiControl): A ProductCecHdmiControl object that contains product cec hdmi control values to set.
Raises:
  • SoundTouchError: If the device is not capable of supporting productcechdmicontrol functions, as determined by a query to the cached supportedURLs web-services api.
    If the control argument is None, or not of type ProductCecHdmiControl.

Note that some SoundTouch devices do not support this functionality. For example, the ST-300 will support this, but the ST-10 will not. This method will first query the device supportedUris to determine if it supports the function; if so, then the request is made to the device; if not, then a SoundTouchError is raised.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.80")

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current product cec hdmi control.
    # note that not all devices support retrieval of this information.
    cfgBefore:ProductCecHdmiControl = None
    cfgBefore = client.GetProductCecHdmiControl()
    print("\nCurrent product cec hdmi control value: \n%s" % cfgBefore.ToString())

    # create new tone controls object.
    cfgUpdate:ProductCecHdmiControl = ProductCecHdmiControl()

    # for testing purposes, toggle the value from OFF to ON or vice versa.
    # if the level is currently ON, then we will set to OFF.
    cfgUpdate.CecMode = ProductCecHdmiModes.OFF
    if cfgUpdate.CecMode == cfgBefore.CecMode:
        cfgUpdate.CecMode = ProductCecHdmiModes.ON
    print("\nSetting product cec hdmi control to '%s' (from '%s') ..." % (cfgUpdate.CecMode, cfgBefore.CecMode))

    # update product cec hdmi control.
    client.SetProductCecHdmiControl(cfgUpdate)

    # get current product cec hdmi control.
    cfgAfter:ProductCecHdmiControl = client.GetProductCecHdmiControl(True)
    print("\nChanged product cec hdmi control: \n%s" % (cfgAfter.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

finally:

    if cfgBefore is not None:

        # restore product cec hdmi control to original values.
        client.SetProductCecHdmiControl(cfgBefore)            

        # get current product cec hdmi control.
        cfgAfter:ProductCecHdmiControl = client.GetProductCecHdmiControl(True)
        print("\nRestored product cec hdmi control: \n%s" % (cfgAfter.ToString()))

Sends a user play control type command to stop / pause / play / resume media content playback.

Arguments:
  • userPlayControlType (UserPlayControlTypes): User play control type to send.
Raises:
  • SoundTouchError: userPlayControlType argument was not supplied, or not of type UserPlayControlTypes.

No exception is raised if the device is currently in standby mode.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # note that PANDORA is currently the only source that supports ratings.
    # ratings are stored in the artist profile under "My Collection" settings.
    # if a ThumbsDown rating is assigned, then the current track play will stop
    # and advance to the next track.

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # pause media that is currently playing.
    print("\nPause media that is currently playing ...")
    client.SetUserPlayControl(UserPlayControlTypes.Pause)

    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    # play media that is currently paused.
    print("\nPlay media that is currently paused. ...")
    client.SetUserPlayControl(UserPlayControlTypes.Play)

    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    # stop media that is currently playing.
    print("\nStop media that is currently playing ...")
    client.SetUserPlayControl(UserPlayControlTypes.Stop)

    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    # play media that is currently paused.
    print("\nPlay media that is currently stopped. ...")
    client.SetUserPlayControl(UserPlayControlTypes.Play)

    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

Rates the currently playing media, if ratings are supported.

Arguments:
  • ratingType (UserRatingTypes): Rating to assign.
Raises:
  • SoundTouchError: rating argument was not supplied, or not of type UserRatingTypes.

No exception is raised if the device is currently in standby mode.

No exception is raised if the NowPlaying content does not support ratings. Check the NowPlayingStatus.IsRatingEnabled property to determine if the content supports ratings or not.

PANDORA is currently the only source that supports ratings. Ratings are stored in the artist profile under "My Collection" settings. If a ThumbsDown rating is assigned, then the current track play will stop and advance to the next track.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # note that PANDORA is currently the only source that supports ratings.
    # ratings are stored in the artist profile under "My Collection" settings.
    # if a ThumbsDown rating is assigned, then the current track play will stop
    # and advance to the next track.

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # rate nowplaying content.
    print("\nRating Now Playing Content with ThumbsUp ...")
    client.SetUserRating(UserRatingTypes.ThumbsUp)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SetUserTrackControl( self, userTrackControlType: bosesoundtouchapi.models.usertrackcontroltypes.UserTrackControlTypes, startSecond: int = None) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Sends a user track control type command to control track playback (next, previous, repeat, shuffle, etc).

Arguments:
  • userTrackControlType (UserTrackControlTypes): User track control type to send.
  • startSecond (int): Starting position (in seconds) of where to start playing the media content. This argument is only valid for UserTrackControlTypes.SEEK_TO_TIME requests.
Raises:
  • SoundTouchError: userTrackControlType argument was not supplied, or not of type UserTrackControlTypes.

No exception is raised if the device is currently in standby mode.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # note that PANDORA is currently the only source that supports ratings.
    # ratings are stored in the artist profile under "My Collection" settings.
    # if a ThumbsDown rating is assigned, then the current track play will stop
    # and advance to the next track.

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("NowPlaying Track = '%s'" % nowPlaying.Track)

    # play next track.
    print("\nPlay next track ...\n")
    client.SetUserTrackControl(UserTrackControlTypes.Next)
    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("NowPlaying Track = '%s'" % nowPlaying.Track)

    # play previous track.
    print("\nRestart track from beginning (after 10 seconds) ...\n")
    time.sleep(10)
    client.SetUserTrackControl(UserTrackControlTypes.Previous)
    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("NowPlaying Track = '%s'" % nowPlaying.Track)

    # play previous track.
    print("\nFORCE Play previous track (after 10 seconds) ...\n")
    time.sleep(10)
    client.SetUserTrackControl(UserTrackControlTypes.PreviousForce)
    time.sleep(3)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("NowPlaying Track = '%s'" % nowPlaying.Track)

except Exception as ex:

    print("** Exception: %s" % str(ex))

def SetVolumeLevel( self, level: int) -> bosesoundtouchapi.soundtouchmessage.SoundTouchMessage:

Sets the device volume level to the given level.

Arguments:
  • level (int): Volume level to set, in the range of 0 (mute) to 100 (full volume).

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current volume level.
    volumeBefore:Volume = client.GetVolume(True)
    print("\nCurrent Volume Levels: %s" % (volumeBefore.ToString()))

    # for testing purposes, use a volume of 30.  if the volume is currently at 30,
    # then we will use a volume of 25.
    newLevel:int = 30
    if volumeBefore.Actual == newLevel:
        newLevel = 25
    print("\nSetting Volume level to %d (from %s) ..." % (newLevel, volumeBefore.Actual))

    # set volume to specific level.
    client.SetVolumeLevel(newLevel)

    # get current volume level.
    volumeAfter:Volume = client.GetVolume(True)
    print("\nChanged Volume Levels: %s" % (volumeAfter.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

Stores the given Preset to the device's list of presets.

Arguments:
  • item (Preset): The Preset object to store.
Returns:

A PresetList object that contains the updated preset list configuration of the device.

Raises:
  • Exception: If the command fails for any reason.

Most SoundTouch devices can only store 6 presets in their internal memory. The Preset.preset_id property controls what slot the stored preset gets placed in. If a preset already exists in a slot, then it is over-written with the newly stored preset. If a preset with the same details exists in another slot, then the duplicate preset is removed and its slot is emptied.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # create a new preset - radio station.
    new_preset_radio:Preset = Preset(
        4,
        time.time(),
        None,
        "TUNEIN",
        "stationurl",
        "/v1/playback/station/s309605",
        "",
        True,
        "My New Preset",
        "http://cdn-profiles.tunein.com/s309605/images/logog.png?t=637986891960000000"
        )

    print("Storing Preset: '%s' - %s" % (new_preset_radio.Name, new_preset_radio.Location))

    # store preset.
    presetList:PresetList = client.StorePreset(new_preset_radio)
    print(presetList.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def StoreSnapshot(self) -> None:

Stores selected portions of the configuration so that they can be easily restored with the RestoreSnapshot method.

The following settings will be stored to the snapshot dictionary by default:

  • SoundTouchNodes.nowPlaying.Path - playing content.
  • SoundTouchNodes.volume.Path - volume level and mute status.

The SnapshotSettings dictionary is cleared prior to storing any settings.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current settings that will be restored by the snapshot.
    print("** Settings before StoreSnapshot ... **")
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("Now Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))
    volume:Volume = client.GetVolume(True)
    print("Volume     : %s" % (volume.ToString()))

    # store current settings to snapshot.
    print("\n** Storing Snapshot ... **")
    client.StoreSnapshot()
    print("\n** Snapshot stored **\n")

    # select a different source.
    print("Changing Source ...")
    client.SelectSource(SoundTouchSources.BLUETOOTH)

    # change the volume level.
    print("Changing Volume to 30 ...")
    client.SetVolumeLevel(30)

    # mute the device.
    print("Changing Mute to On ...")
    client.MuteOn()

    # get current settings before the snapshot restore.
    print("\n** Settings before RestoreSnapshot ... **")
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("Now Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))
    volume:Volume = client.GetVolume(True)
    print("Volume     : %s" % (volume.ToString()))

    # if you don't want to restore a configuration, then simply delete 
    # it from the snapshot dictionary, like so:
    # if SoundTouchNodes.volume.Path in client.SnapshotSettings:
    #     client.SnapshotSettings.pop(SoundTouchNodes.volume.Path)

    # restore settings from snapshot.
    print("\n** Restoring Snapshot ... **")
    client.RestoreSnapshot()

    # get current settings after the snapshot restore.
    print("\n** Settings after RestoreSnapshot (should match settings before StoreSnapshot) ... **")
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("Now Playing: '%s' - '%s'" % (nowPlaying.ContentItem.Name, nowPlaying.ContentItem.Location))
    volume:Volume = client.GetVolume(True)
    print("Volume     : %s" % (volume.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def ThumbsDown(self) -> None:

Sets a thumbs down rating for the currently playing media.

This will first make a call to GetNowPlayingStatus() method to ensure ratings are enabled for the now playing media. If not enabled, then the request is ignored and no exception is raised.

Note that this method should only be used with source music services that support ratings (e.g. PANDORA, SPOTIFY, etc). The rating value is actually stored with the music service, and is not located on the SoundTouch device itself.

Note that for some music services (e.g. PANDORA), the now playing selection will change immediately once this method processing completes; there is no code in this API that forces the change.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # are rating functions allowed for currently playing media?
    if nowPlaying.IsRatingEnabled:

        # rate the currently playing media.
        client.ThumbsDown()

        # give the device time to process the change.
        time.sleep(1)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    else:

        print("\Ratings are not enabled for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

def ThumbsUp(self) -> None:

Sets a thumbs up rating for the currently playing media.

This will first make a call to GetNowPlayingStatus() method to ensure ratings are enabled for the now playing media. If not enabled, then the request is ignored and no exception is raised.

Note that this method should only be used with source music services that support ratings (e.g. PANDORA, SPOTIFY, etc). The rating value is actually stored with the music service, and is not located on the SoundTouch device itself.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
import time

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get current nowPlaying status.
    nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
    print("\nCurrent Now Playing Status:\n%s" % nowPlaying.ToString())

    # are rating functions allowed for currently playing media?
    if nowPlaying.IsRatingEnabled:

        # rate the currently playing media.
        client.ThumbsUp()

        # give the device time to process the change.
        time.sleep(1)

        # get current nowPlaying status.
        nowPlaying:NowPlayingStatus = client.GetNowPlayingStatus(True)
        print("\nUpdated Now Playing Status:\n%s" % nowPlaying.ToString())

    else:

        print("\Ratings are not enabled for currently playing media")

except Exception as ex:

    print("** Exception: %s" % str(ex))

Toggles the given zone member in the master device's zone. If the member exists in the zone then it is removed; if the member does not exist in the zone, then it is added.

Arguments:
  • member (ZoneMember): A ZoneMember object to add to / remove from the master zone.
  • delay (int): Time delay (in seconds) to wait AFTER processing the zone member changes. This delay will give the device time to process the change before another command is accepted.
    Default is 3; value range is 0 - 10.
Raises:
  • SoundTouchError: Master zone status could not be retrieved.
    Member argument was not supplied, or is not of type ZoneMember.
    Member argument did not specify a value for the DeviceId property.

The SoundTouch master device cannot find zone members without their device id.

A new zone will automatically be created if need be.

This method should only be called on the master device of a zone.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # build zone member to toggle.
    zoneMember:ZoneMember = ZoneMember("192.168.1.82", "5072249B7B1D")

    # get current zone configuration status.
    zoneStatus:Zone = client.GetZoneStatus()
    print("\nCurrent Zone Status:\n%s" % zoneStatus.ToString(True))

    # toggle zone membership in the master zone configuration of the device.
    print("\nToggling zone member:\n%s" % (zoneMember.ToString()))
    msg:SoundTouchMessage = client.ToggleZoneMember(zoneMember)

    # get current zone configuration status.
    zoneStatus:Zone = client.GetZoneStatus()
    print("\nCurrent Zone Status:\n%s" % zoneStatus.ToString(True))

    # toggle zone membership in the master zone configuration of the device.
    print("\nToggling zone member:\n%s" % (zoneMember.ToString()))
    msg:SoundTouchMessage = client.ToggleZoneMember(zoneMember)

    # get current zone configuration status.
    zoneStatus:Zone = client.GetZoneStatus()
    print("\nCurrent Zone Status:\n%s" % zoneStatus.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def ToString(self) -> str:

Returns a displayable string representation of the class.

def UpdateGroupStereoPairName(self, name: str) -> bosesoundtouchapi.models.group.Group:

Updates the name of the current left / right stereo pair speaker group configuration for the device.

Arguments:
  • name (str): New name to assign to the group.
Returns:

A Group object that contains the result.

The ST-10 is the only SoundTouch product that supports stereo pair groups.

An existing left / right stereo pair speaker group must exist prior to calling this method.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    group:Group = client.GetGroupStereoPairStatus()
    print("\nGroup Status Before:\n%s" % group.ToString(True))

    # update group name.
    print("\nRenaming Group ...")
    groupAfter:Group = client.UpdateGroupStereoPairName("My Updated GroupName")
    print("\nGroup Status After:\n%s" % groupAfter.ToString(True))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def UpdateNowPlayingStatusForSource( self, source: str, sourceAccount: str, album: str = None, artist: str = None, artistId: str = None, artUrl: str = None, description: str = None, duration: int = None, genre: str = None, playStatus: str = None, position: int = None, sessionId: str = None, stationLocation: str = None, stationName: str = None, track: str = None, trackId: str = None) -> bosesoundtouchapi.models.nowplayingstatus.NowPlayingStatus:

Updates the NowPlayingStatus object for a given source and sourceAccount.

Arguments:
  • source (SoundTouchSources|str): Source input this content item is played with.
  • sourceAccount (str): Source account this content item is played with.
  • album (str): The album of the playing track (if present).
  • artist (str): The creator of the track (if present).
  • artistId (str): Unique identifier of the artist, as provided by the source music service (if present).
  • artUrl (str): A url link to the art image of the station (if present).
  • description (str): A brief description that was added to the track (if present).
  • duration (int): The track's duration (if present).
  • genre (str): The genre of the track (if present).
  • playStatus (str): Indicates whether the device is currently playing the embedded track.
  • position (int): The current position of the playing media (if present).
  • sessionId (str): Unique identifier of the session, as provided by the source music service (if present).
  • stationLocation (str): The station's location.
  • stationName (str): The station's name (if present).
  • track (str): The current media track name (if present).
  • trackId (str): Unique identifier of the track, as provided by the source music service (if present).
Returns:

A NowPlayingStatus that was built and added to the cache.

Use this method to update a NowPlayingStatus, which can be used by external entities that want to keep track of external sources that are currently playing on the SoundTouch device. For example, you could have a Home Assistant media player playing TV content on the SoundTouch and it could keep track of what is currently playing for a source that the SoundTouch API does not track (e.g. PRODUCT:TV, PRODUCT:HDMI_1, etc).

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *
from bosesoundtouchapi.uri import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    nowPlayingStatus:NowPlayingStatus = client.GetNowPlayingStatus()
    print("Device Status:\n%s" % nowPlayingStatus.ToString())

    # set source-specific variables.
    source:str = "PRODUCT"
    sourceAccount:str = "TV"

    # update source-specific NowPlayingStatus.
    client.UpdateNowPlayingStatusForSource(source=source,
                                           sourceAccount=sourceAccount,
                                           album="My Album Name",
                                           artist="Artist Name",
                                           track="Track # 1",
                                           artUrl="")

    # get cached configuration directly from the configuration manager dictionary.
    cacheKey = "%s-%s:%s" % (SoundTouchNodes.nowPlaying.Path, source, sourceAccount)
    if cacheKey in client.ConfigurationCache:
        nowPlayingStatus:NowPlayingStatus = client.ConfigurationCache[cacheKey]
        print("\nSource-Specific Status (%s):\n%s" % (cacheKey, nowPlayingStatus.ToString()))

except Exception as ex:

    print("** Exception: %s" % str(ex))

def VolumeDown(self) -> None:

Decrease the volume of the device by one.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(before) %s" % volume.ToString())

    # tick volume down one notch.
    client.VolumeDown()

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(after)  %s" % volume.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))

def VolumeUp(self) -> None:

Increase the volume of the device by one.

Sample Code

from bosesoundtouchapi import *
from bosesoundtouchapi.models import *

try:

    # create SoundTouch device instance.
    device:SoundTouchDevice = SoundTouchDevice("192.168.1.81") # Bose SoundTouch 10

    # create SoundTouch client instance from device.
    client:SoundTouchClient = SoundTouchClient(device)

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(before) %s" % volume.ToString())

    # tick volume up one notch.
    client.VolumeUp()

    # get real-time configuration from the device.
    volume:Volume = client.GetVolume()
    print("(after)  %s" % volume.ToString())

except Exception as ex:

    print("** Exception: %s" % str(ex))