soco.events module

Classes to handle Sonos UPnP Events and Subscriptions.

soco.events.parse_event_xml(xml_event)[source]

Parse the body of a UPnP event.

Parameters:xml_event (bytes) – bytes containing the body of the event encoded with utf-8.
Returns:A dict with keys representing the evented variables. The relevant value will usually be a string representation of the variable’s value, but may on occasion be:
  • a dict (eg when the volume changes, the value will itself be a dict containing the volume for each channel: {'Volume': {'LF': '100', 'RF': '100', 'Master': '36'}})
  • an instance of a DidlObject subclass (eg if it represents track metadata).
Return type:dict

Example

Run this code, and change your volume, tracks etc:

from __future__ import print_function
try:
    from queue import Empty
except:  # Py2.7
    from Queue import Empty

import soco
from pprint import pprint
from soco.events import event_listener
# pick a device at random
device = soco.discover().pop()
print (device.player_name)
sub = device.renderingControl.subscribe()
sub2 = device.avTransport.subscribe()

while True:
    try:
        event = sub.events.get(timeout=0.5)
        pprint (event.variables)
    except Empty:
        pass
    try:
        event = sub2.events.get(timeout=0.5)
        pprint (event.variables)
    except Empty:
        pass

    except KeyboardInterrupt:
        sub.unsubscribe()
        sub2.unsubscribe()
        event_listener.stop()
        break
class soco.events.Event(sid, seq, service, timestamp, variables=None)[source]

A read-only object representing a received event.

The values of the evented variables can be accessed via the variables dict, or as attributes on the instance itself. You should treat all attributes as read-only.

Parameters:
  • sid (str) – the subscription id.
  • seq (str) – the event sequence number for that subscription.
  • timestamp (str) – the time that the event was received (from Python’s time.time function).
  • service (str) – the service which is subscribed to the event.
  • variables (dict, optional) – contains the {names: values} of the evented variables. Defaults to None.
Raises:

AttributeError – Not all attributes are returned with each event. An AttributeError will be raised if you attempt to access as an attribute a variable which was not returned in the event.

Example

>>> print event.variables['transport_state']
'STOPPED'
>>> print event.transport_state
'STOPPED'
__setattr__(name, value)[source]

Disable (most) attempts to set attributes.

This is not completely foolproof. It just acts as a warning! See object.__setattr__.

class soco.events.EventServer(server_address, RequestHandlerClass, bind_and_activate=True)[source]

A TCP server which handles each new request in a new thread.

Constructor. May be extended, do not override.

class soco.events.EventNotifyHandler(request, client_address, server)[source]

Handles HTTP NOTIFY Verbs sent to the listener server.

do_NOTIFY()[source]

Serve a NOTIFY request.

A NOTIFY request will be sent by a Sonos device when a state variable changes. See the UPnP Spec §4.3 [pdf] for details.

class soco.events.EventServerThread(address)[source]

The thread in which the event listener server will run.

Parameters:address (tuple) – The (ip, port) address on which the server should listen.
stop_flag = None

threading.Event: Used to signal that the server should stop.

address = None

tuple: The (ip, port) address on which the server is configured to listen.

run()[source]

Start the server on the local IP at port 1400 (default).

Handling of requests is delegated to an instance of the EventNotifyHandler class.

class soco.events.EventListener[source]

The Event Listener.

Runs an http server in a thread which is an endpoint for NOTIFY requests from Sonos devices.

is_running = None

bool: Indicates whether the server is currently running

address = None

tuple: The address (ip, port) on which the server is configured to listen.

start(any_zone)[source]

Start the event listener listening on the local machine at port 1400 (default)

Make sure that your firewall allows connections to this port

Parameters:any_zone (SoCo) – Any Sonos device on the network. It does not matter which device. It is used only to find a local IP address reachable by the Sonos net.

Note

The port on which the event listener listens is configurable. See config.EVENT_LISTENER_PORT

stop()[source]

Stop the event listener.

class soco.events.Subscription(service, event_queue=None)[source]

A class representing the subscription to a UPnP event.

Parameters:
  • service (Service) – The SoCo Service to which the subscription should be made.
  • event_queue (Queue) – A queue on which received events will be put. If not specified, a queue will be created and used.
sid = None

str: A unique ID for this subscription

timeout = None

int: The amount of time in seconds until the subscription expires.

is_subscribed = None

bool: An indication of whether the subscription is subscribed.

events = None

Queue: The queue on which events are placed.

requested_timeout = None

int: The period (seconds) for which the subscription is requested

subscribe(requested_timeout=None, auto_renew=False)[source]

Subscribe to the service.

If requested_timeout is provided, a subscription valid for that number of seconds will be requested, but not guaranteed. Check timeout on return to find out what period of validity is actually allocated.

Note

SoCo will try to unsubscribe any subscriptions which are still subscribed on program termination, but it is good practice for you to clean up by making sure that you call unsubscribe() yourself.

Parameters:
  • requested_timeout (int, optional) – The timeout to be requested.
  • auto_renew (bool, optional) – If True, renew the subscription automatically shortly before timeout. Default False.
renew(requested_timeout=None)[source]

Renew the event subscription.

You should not try to renew a subscription which has been unsubscribed, or once it has expired.

Parameters:requested_timeout (int, optional) – The period for which a renewal request should be made. If None (the default), use the timeout requested on subscription.
unsubscribe()[source]

Unsubscribe from the service’s events.

Once unsubscribed, a Subscription instance should not be reused

time_left

int: The amount of time left until the subscription expires (seconds)

If the subscription is unsubscribed (or not yet subscribed), time_left is 0.