class Renderer(object): """Raumfeld Renderer""" def __init__(self, name, udn, location): self._name = name self._udn = udn self._location = location scheme, netloc, _, _, _, _ = urllib2.urlparse.urlparse(location) self._address = '{0}://{1}'.format(scheme, netloc) # ToDo: get correct ControlLocation from the XML file self._renderingControl = SoapClient( location='{0}/RenderingControl/ctrl'.format(self._address), action='urn:upnp-org:serviceId:RenderingControl#', namespace='http://schemas.xmlsoap.org/soap/envelope/', soap_ns='soap', ns='s', exceptions=False) self._avTransport = SoapClient( location='{0}/AVTransport/ctrl'.format(self._address), action='urn:schemas-upnp-org:service:AVTransport:1#', namespace='http://schemas.xmlsoap.org/soap/envelope/', soap_ns='soap', ns='s', exceptions=False) def reinit(self, name, udn, location): self._name = name self._udn = udn self._location = location scheme, netloc, _, _, _, _ = urllib2.urlparse.urlparse(location) self._address = '{0}://{1}'.format(scheme, netloc) # ToDo: get correct ControlLocation from the XML file self._renderingControl = SoapClient( location='{0}/RenderingControl/ctrl'.format(self._address), action='urn:upnp-org:serviceId:RenderingControl#', namespace='http://schemas.xmlsoap.org/soap/envelope/', soap_ns='soap', ns='s', exceptions=False) self._avTransport = SoapClient( location='{0}/AVTransport/ctrl'.format(self._address), action='urn:schemas-upnp-org:service:AVTransport:1#', namespace='http://schemas.xmlsoap.org/soap/envelope/', soap_ns='soap', ns='s', exceptions=False) @property def Name(self): """Get the name of the renderer""" return self._name @property def UDN(self): """Get the UDN of the renderer""" return self._udn @property def Location(self): """Get the location URI""" return self._location @property def Address(self): """Get the network address""" return self._address def play(self, uri=None, meta=""): """Start playing :param uri: (optional) play a specific uri :param meta: (optional) meta data in DIDL-Lite format """ if uri: self._avTransport.SetAVTransportURI(InstanceID=0, CurrentURI=uri, CurrentURIMetaData=meta) else: self._avTransport.Play(InstanceID=1, Speed=2) def next(self): """Next""" self._avTransport.Next(InstanceID=1) def previous(self): """Previous""" self._avTransport.Previous(InstanceID=1) def pause(self): """Pause""" self._avTransport.Pause(InstanceID=1) def seek(self, target, unit='ABS_TIME'): """Seek; unit = _ABS_TIME_/REL_TIME/TRACK_NR""" return self._avTransport.Seek(InstanceID=1, Unit=unit, Target=target) def stop(self): """Stop""" self._avTransport.Stop(InstanceID=1) @property def volume(self): """get/set the current volume""" try: return int( self._renderingControl.GetVolume(InstanceID=1).CurrentVolume) except: return 0 @volume.setter def volume(self, value): self._renderingControl.SetVolume(InstanceID=1, DesiredVolume=value) def changeVolume(self, value): self._renderingControl.ChangeVolume(InstanceID=1, Amount=value) @property def mute(self): """get/set the current mute state""" response = self._renderingControl.GetMute(InstanceID=1, Channel=1) return int(response.CurrentMute) == 1 @mute.setter def mute(self, value): self._renderingControl.SetMute(InstanceID=1, DesiredMute=1 if value else 0, Channel=1)
class Zone(object): """Raumfeld Zone""" def __init__(self, name, udn, location): self._rooms = [] self._udn = udn self._name = name self._location = location scheme, netloc, _, _, _, _ = urllib2.urlparse.urlparse(location) self._address = '{0}://{1}'.format(scheme, netloc) # ToDo: get correct ControlLocation from the XML file self._renderingControl = SoapClient( location='{0}/RenderingService/Control'.format(self._address), action='urn:upnp-org:serviceId:RenderingControl#', namespace='http://schemas.xmlsoap.org/soap/envelope/', soap_ns='soap', ns='s', exceptions=False) self._avTransport = SoapClient( location='{0}/TransportService/Control'.format(self._address), action='urn:schemas-upnp-org:service:AVTransport:1#', namespace='http://schemas.xmlsoap.org/soap/envelope/', soap_ns='soap', ns='s', exceptions=False) def _removeRoomByUDN(self, udn): """Remove the room with the UDN from the list of rooms""" for room_element in self._rooms: if room_element.UDN == udn: self._rooms.remove(room_element) def getRoomByUDN(self, udn): """Try to get the room of the zone by its UDN""" for room_element in self._rooms: if room_element.UDN == udn: return room_element return None @property def Name(self): """Get the name of the zone""" return self._name @property def UDN(self): """Get the UDN of the zone""" return self._udn @property def Location(self): """Get the location URI""" return self._location @property def Address(self): """Get the network address""" return self._address def play(self, uri=None, meta=None): """Start playing :param uri: (optional) play a specific uri """ if meta: self._avTransport.SetAVTransportURI( InstanceID=0, CurrentURI=uri, CurrentURIMetaData=meta) elif uri: self._avTransport.SetAVTransportURI( InstanceID=0, CurrentURI=uri, CurrentURIMetaData="") else: self._avTransport.Play(InstanceID=1, Speed=2) def bend(self, uri=None, meta=None): """BendAVTransportURI""" self._avTransport.BendAVTransportURI( InstanceID=0, CurrentURI=uri, CurrentURIMetaData=meta) def next(self): """Next""" self._avTransport.Next(InstanceID=1) def previous(self): """Previous""" self._avTransport.Previous(InstanceID=1) def pause(self): """Pause""" self._avTransport.Pause(InstanceID=1) def seek(self, target, unit = 'ABS_TIME'): """Seek; unit = _ABS_TIME_/REL_TIME/TRACK_NR""" return self._avTransport.Seek(InstanceID=1, Unit = unit, Target = target) @property def transport_state(self): """Get Current Transport State""" return (self._avTransport.GetTransportInfo(InstanceID=1) .CurrentTransportState) @property def volume(self): """get/set the current volume""" try: return int(self._renderingControl.GetVolume(InstanceID=1).CurrentVolume) except: return 0 @volume.setter def volume(self, value): self._renderingControl.SetVolume(InstanceID=1, DesiredVolume=value) def changeVolume(self, value): self._renderingControl.ChangeVolume(InstanceID=1, Amount=value) @property def mute(self): """get/set the current mute state""" response = self._renderingControl.GetMute(InstanceID=1, Channel=1) return int(response.CurrentMute) == 1 @mute.setter def mute(self, value): self._renderingControl.SetMute(InstanceID=1, DesiredMute=1 if value else 0, Channel=1) @property def uri(self): """Get the uri of the currently played medium""" return self._avTransport.GetMediaInfo(InstanceID=1).CurrentURI @property def uri_metadata(self): """Get CurrentURIMetaData""" return self._avTransport.GetMediaInfo(InstanceID=1).CurrentURIMetaData @property def media_info(self): """Get TrackURI""" info = self._avTransport.GetMediaInfo(InstanceID=1) media_dic = {'tracks' : info.NrTracks, 'media_duration' : info.MediaDuration, 'uri_metadata' : info.CurrentURIMetaData, 'uri' : info.CurrentURI} return media_dic @property def position_info(self): """Get TrackURI""" info = self._avTransport.GetPositionInfo(InstanceID=1) pos_dic = {'track' : info.Track, 'track_duration' : info.TrackDuration, 'track_metadata' : info.TrackMetaData, 'track_uri' : info.TrackURI, 'rel_time' : info.RelTime, 'abs_time' : info.AbsTime} return pos_dic @property def track_uri(self): """Get TrackURI""" return self._avTransport.GetPositionInfo(InstanceID=1).TrackURI @property def track_metadata(self): """Get TrackURIMetaData""" return self._avTransport.GetPositionInfo(InstanceID=1).TrackMetaData @property def track_duration(self): """Get TrackDuration""" return self._avTransport.GetPositionInfo(InstanceID=1).TrackDuration @property def track_rel_time(self): """Get RelTime""" return self._avTransport.GetPositionInfo(InstanceID=1).RelTime @property def track_abs_time(self): """Get AbsTime""" return self._avTransport.GetPositionInfo(InstanceID=1).AbsTime def getRooms(self): """Returns the list of rooms in this zone""" return self._rooms; def getRoomsByName(self, name): """Searches for rooms with a special name""" rooms= [] for room in self._rooms: if room.Name.find(name): rooms.append(room) return rooms