Exemplo n.º 1
0
    def update(self):
        """Get the latest player details from the device."""

        if self._slave_mode:
            return True

        if self._upnp_device is None:
            for entry in self.upnp_discover(UPNP_TIMEOUT):
                if entry.friendly_name == self._devicename:
                    self._upnp_device = upnpclient.Device(entry.location)
                    break

        self._update_device_status()

        self._update_player_status()

        self._update_transport_status_via_upnp()

        self._update_media_info_via_upnp()

        # Fall back on id3 if we didn't get media info via upnp
        # TODO - Makes updates very slow. Can we avoid or do this async?
        # if self._media_title is None or len(self._media_title) == 0:
        #     if self._media_uri is not None and self._new_song:
        #         self._update_media_info_from_id3()

        self._update_slaves()

        return True
Exemplo n.º 2
0
def set_mute(
    location,
    desired_mute=True,
    channel="Master",
    instance_id=0,
):
    """Sets the mute status of a rendering service.

    Applies to:
    Digital Media Player
    Virtual Media Player

    Parameters:
    location -- URL to the device description XML of the rendering device.
    instance_id
    channel --
    desired_mute --- Bolean value of True activaes the mute status and a
    value of False deactivates the mute status.
    """
    if desired_mute == True:
        desired_mute = "1"
    else:
        desired_mute = "0"

    device = upnpclient.Device(location)
    device.RenderingControl.SetMute(InstanceID=instance_id,
                                    Channel=channel,
                                    DesiredMute=desired_mute)
def main():
    d = upnpclient.Device("http://miracast-sidescreen:60099/")

    print("AVTransport.GetCurrentTransportActions")
    print("    ", d.AVTransport.GetCurrentTransportActions(InstanceID=0))
    print("AVTransport.GetDeviceCapabilities")
    print("    ", d.AVTransport.GetDeviceCapabilities(InstanceID=0))
    print("AVTransport.GetMediaInfo")
    print("    ", d.AVTransport.GetMediaInfo(InstanceID=0))
    print("AVTransport.GetPositionInfo")
    print("    ", d.AVTransport.GetPositionInfo(InstanceID=0))
    print("AVTransport.GetTransportInfo")
    print("    ", d.AVTransport.GetTransportInfo(InstanceID=0))
    print("AVTransport.GetTransportSettings")
    print("    ", d.AVTransport.GetTransportSettings(InstanceID=0))
    print("ConnectionManager.GetCurrentConnectionIDs")
    print("    ", d.ConnectionManager.GetCurrentConnectionIDs())
    print("ConnectionManager.GetCurrentConnectionInfo")
    print("    ", d.ConnectionManager.GetCurrentConnectionInfo(ConnectionID=0))
    print("ConnectionManager.GetProtocolInfo")
    print("    ", d.ConnectionManager.GetProtocolInfo())
    print("RenderingControl.GetBrightness")
    print("    ", d.RenderingControl.GetBrightness(InstanceID=0))
    print("RenderingControl.GetContrast")
    print("    ", d.RenderingControl.GetContrast(InstanceID=0))
    print("RenderingControl.GetMute")
    print("    ", d.RenderingControl.GetMute(InstanceID=0, Channel='Master'))
    print("RenderingControl.GetVolume")
    print("    ", d.RenderingControl.GetVolume(InstanceID=0, Channel='Master'))
    print("RenderingControl.ListPresets")
    print("    ", d.RenderingControl.ListPresets(InstanceID=0))
Exemplo n.º 4
0
 def init_device(self):
     if self.upnp_obj is None:
         try:
             self.upnp_obj = upnpclient.Device(self.upnp_location,
                                               self.name)
         except:  # noqa: E722
             _LOGGER.warning(f"{traceback.format_exc()}")
             self.upnp_obj = None
     return self.upnp_obj
Exemplo n.º 5
0
	def connect(self, uri):
		try:
			self.device = upnpclient.Device(uri)
			self.status = 1
			self.log("Connected to "+ uri)
			self.send("connection", "ready")
		except:
			self.status = 0
			self.log("Unable to connect to "+ uri)
			self.send("connection", "failed")
Exemplo n.º 6
0
def set_av_transport_uri(location,
                         current_uri,
                         current_uri_meta_data="",
                         instance_id=0):
    device = upnpclient.Device(location)
    device.AVTransport.SetAVTransportURI(
        InstanceID=instance_id,
        CurrentURI=current_uri,
        CurrentURIMetaData=current_uri_meta_data,
    )
Exemplo n.º 7
0
def main():
    d = upnpclient.Device("http://miracast-sidescreen:60099/")

    for s in d.services:
        print("  ", s.name)
        for a in s.actions:
            print("    -", a.name)
            for arg in a.argsdef_in:
                print("        %s:%s (%s)" %
                      (arg[0], arg[1]['datatype'], arg[1]['allowed_values']))
 def upnp_discover(self, timeout=5):
     devices = {}
     for entry in netdisco.ssdp.scan(timeout):
         if entry.location in devices:
             continue
         try:
             devices[entry.location] = upnpclient.Device(entry.location)
         except Exception as exc:
             _LOGGER.debug('Error \'%s\' for %s', exc, entry.location)
     return list(devices.values())
def upnp_discover(timeout=5):
    devices = {}
    for entry in netdisco.ssdp.scan(timeout):
        if entry.location in devices:
            continue
        try:
            devices[entry.location] = upnpclient.Device(entry.location)
        except Exception as exc:
            pass
    return list(devices.values())
Exemplo n.º 10
0
def getDevicesWithDefault(deviceURL):
    global cachedDevices
    startIfNeeded()
    if deviceURL:
        devices = [upnpclient.Device(deviceURL)]
    else:
        if not cachedDevices:
            #Very quick scan because we let the background thread handle the slow stuff.
            cachedDevices = upnpclient.discover(timeout=1)
        devices = cachedDevices
    return devices
Exemplo n.º 11
0
def change_volume(location, amount, instance_id=0):
    """Changes the volume of all rooms in a zone up or down.

    Applies to:
    Digital Media Player
    Virtual Media Player

    Parameters:
    location -- URL to the device description XML of the rendering device.
    amount -- Amount of volume change.
    instance_id --
    """
    device = upnpclient.Device(location)
    device.RenderingControl.ChangeVolume(InstanceID=instance_id, Amount=amount)
def load_igd(filename):
    if not os.path.exists(filename):
        return
    with open(filename, "r") as f:
        try:
            igd_device = json.load(f)
            device_name = igd_device.get("device_name")
            if not device_name:
                return
            logger.debug("Using URL %s", device_name)
            igd = upnpclient.Device(device_name)
            return igd
        except Exception:
            logger.exception("Failed to read %s", filename)
Exemplo n.º 13
0
 def connect_button_clicked(self):
     url = self.serverUrl.text()
     try:
         print("Looking up service details for %r..." % url)
         device = upnpclient.Device(url)
     except Exception as exc:
         print("Failure :(")
         print(exc)
         msgbox = QMessageBox()
         msgbox.setText("Doh")
         msgbox.setInformativeText(str(exc))
         msgbox.exec_()
         return
     self.add_device(device)
Exemplo n.º 14
0
    def startup(self):
        global port
        global ip

        config = configparser.ConfigParser()
        try:
            config.read(scriptDir + os.path.sep + "config.ini")
            up = config.get("SETTINGS", "ip")
            d = upnpclient.Device(up)
        except:
            Ui_MainWindow.error_message("No valid IP given please edit configfile")
            exit()

        port = get_ports(d)
        ip = get_ip()
Exemplo n.º 15
0
def get_mute(location, channel="Master", instance_id=0):
    """Returns a bolean of the mute status of a rendering service.

    Applies to:
    Digital Media Player
    Virtual Media Player

    Parameters:
    location -- URL to the device description XML of the rendering device.
    instance_id --
    channel --
    """
    device = upnpclient.Device(location)
    response = device.RenderingControl.GetMute(InstanceID=instance_id,
                                               Channel=channel)
    return response["CurrentMute"]
Exemplo n.º 16
0
def get_room_mute(location, room, instance_id=0):
    """Returns the mute status of a rendering service in a room.

    Applies to Virtual Media Player.

    Parameters:
    location -- URL to the device description XML of the rendering device
    in a room.
    room -- The unique device number of the room (UUID). The device must be
    member of the room.
    instance_id --
    """
    device = upnpclient.Device(location)
    response = device.RenderingControl.GetRoomMute(InstanceID=instance_id,
                                                   Room=room)
    return response["CurrentMute"]
Exemplo n.º 17
0
 def test_device_props(self):
     """
     `Device` instance should contain the properties from the XML.
     """
     server = upnp.Device('http://127.0.0.1:%s/upnp/IGD.xml' %
                          self.httpd_port)
     self.assertEqual(
         server.device_type,
         'urn:schemas-upnp-org:device:InternetGatewayDevice:1')
     self.assertEqual(server.friendly_name, 'SpeedTouch 5x6 (0320FJ2PZ)')
     self.assertEqual(server.manufacturer, 'Pannaway')
     self.assertEqual(server.model_description,
                      'DSL Internet Gateway Device')
     self.assertEqual(server.model_name, 'Pannaway')
     self.assertEqual(server.model_number, 'RG-210')
     self.assertEqual(server.serial_number, '0320FJ2PZ')
Exemplo n.º 18
0
def get_volume(location, channel="Master", instance_id=0):
    """Returns the highest volume of rooms in a zone rendering service.

    Applies to:
    Digital Media Player
    Virtual Media Player

    Parameters:
    location -- URL to the device description XML of the rendering device
    in a room.
    channel --
    instance_id --
    """
    device = upnpclient.Device(location)
    response = device.RenderingControl.GetVolume(InstanceID=instance_id,
                                                 Channel=channel)
    return response["CurrentVolume"]
Exemplo n.º 19
0
def set_room_volume(location, room, desired_volume, instance_id=0):
    """Sets the volume of a rendering service in a room.

    Applies to Virtual Media Player.

    Parameters:
    location -- URL to the device description XML of the rendering device.
    room -- The unique device number of the room (UUID). The device must be
    member of the room.
    desired_volume -- Desired volume for the room.
    instance_id --
    value of False deactivates the mute status.
    """
    device = upnpclient.Device(location)
    device.RenderingControl.SetRoomVolume(InstanceID=instance_id,
                                          Room=room,
                                          DesiredVolume=desired_volume)
Exemplo n.º 20
0
def set_volume(location, desired_volume, channel="Master", instance_id=0):
    """Returns the highest volume of rooms in a zone rendering service.

    Applies to:
    Digital Media Player
    Virtual Media Player

    Parameters:
    location -- URL to the device description XML of the rendering device.
    desired_volume -- Desired volume for the zone. Relations between rooms
    are kept.
    channel --
    instance_id --
    """
    device = upnpclient.Device(location)
    device.RenderingControl.SetVolume(InstanceID=instance_id,
                                      Channel=channel,
                                      DesiredVolume=desired_volume)
Exemplo n.º 21
0
 def test_device_headers(self, mock_post):
     headers = dict(test='device')
     device = upnp.Device('http://127.0.0.1:%s/upnp/IGD.xml' %
                          self.httpd_port,
                          http_headers=headers)
     ret = mock.Mock()
     ret.content = """
     <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <s:Body>
           <u:GetSubnetMaskResponse xmlns:u="urn:schemas-upnp-org:service:LANHostConfigManagement:1">
              <NewSubnetMask>255.255.255.0</NewSubnetMask>
           </u:GetSubnetMaskResponse>
        </s:Body>
     </s:Envelope>
     """
     mock_post.return_value = ret
     ret = device('GetSubnetMask')
     _, kwargs = mock_post.call_args
     self.assertEqual(kwargs['headers']['test'], 'device')
Exemplo n.º 22
0
def search(
    location,
    container_id=0,
    search_criteria="",
    filter="*",
    starting_index=0,
    requested_count=0,
    sort_criteria="",
):
    device = upnpclient.Device(location)
    response = device.ContentDirectory.Search(
        ContainerID=container_id,
        SearchCriteria=search_criteria,
        Filter=filter,
        StartingIndex=starting_index,
        RequestedCount=requested_count,
        SortCriteria=sort_criteria,
    )
    return response["Result"]
Exemplo n.º 23
0
def parse_dlna(dlna_server):
    """
    Return a dict of title: url from dlna
    """
    res = [
        s for s in upnpclient.Device("http://{}/rootDesc.xml".format(
            dlna_server)).services if s.name == "ContentDirectory"
    ][0].Browse(
        ObjectID="2$8",
        BrowseFlag="BrowseDirectChildren",
        Filter="",
        StartingIndex=0,
        RequestedCount=100000,
        SortCriteria="",
    )["Result"]

    root = ET.fromstring(res)

    return {item[0].text: item[3].text for item in root}
Exemplo n.º 24
0
def play_system_sound(location, sound="Success", instance_id=0):
    """Plays a one out of two available system sounds.

    Devices have to be online. The sound gets mixed into potentially played
    media.

    Applies to:
    Digital Media Player

    Parameters:
    location -- URL to the device description XML of the rendering device.
    sound -- Valid values are "Success" and "Failure".
    instance_id --
    """
    if sound != "Success":
        sound = "Failure"

    device = upnpclient.Device(location)
    device.RenderingControl.PlaySystemSound(InstanceID=instance_id,
                                            Sound=sound)
Exemplo n.º 25
0
def browse(
    location,
    object_id=0,
    browse_flag=BROWSE_CHILDREN,
    filter="*",
    starting_index=0,
    requested_count=0,
    sort_criteria="",
    http_headers=None,
):
    device = upnpclient.Device(location, http_headers=http_headers)
    response = device.ContentDirectory.Browse(
        ObjectID=object_id,
        BrowseFlag=browse_flag,
        Filter=filter,
        StartingIndex=starting_index,
        RequestedCount=requested_count,
        SortCriteria=sort_criteria,
    )
    return response["Result"]
Exemplo n.º 26
0
 def test_device_auth(self, mock_post):
     auth = ('myuser', 'mypassword')
     device = upnp.Device('http://127.0.0.1:%s/upnp/IGD.xml' %
                          self.httpd_port,
                          http_auth=auth)
     ret = mock.Mock()
     ret.content = """
     <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <s:Body>
           <u:GetSubnetMaskResponse xmlns:u="urn:schemas-upnp-org:service:LANHostConfigManagement:1">
              <NewSubnetMask>255.255.255.0</NewSubnetMask>
           </u:GetSubnetMaskResponse>
        </s:Body>
     </s:Envelope>
     """
     mock_post.return_value = ret
     ret = device('GetSubnetMask')
     _, kwargs = mock_post.call_args
     self.assertIn('auth', kwargs)
     self.assertEqual(kwargs['auth'], auth)
Exemplo n.º 27
0
def upnp_execute_action(information):
    result = dict()
    device = upnpclient.Device(information["location"])
    service_id = information["service"]
    action_name = information["action"]
    found = False
    i = 0
    action = None

    while i < len(device.services) and not found:
        j = 0
        result_service = device.services[i]
        if result_service.service_id == service_id:
            while j < len(device.services[i].actions) and not found:
                result_action = device.services[i].actions[j]
                if result_action.name == action_name:
                    action = result_action
                    found = True
                j += 1
        i += 1

    args_in = information["args_in"]
    for arg, value in args_in.items():
        try:
            args_in[arg] = int(value)
        except Exception as e:
            # stub
            warnings.warn(str(e))

    try:
        action_exec = action(args_in)
        result["data"] = action_exec
        result["status"] = True
    except Exception as e:
        warnings.warn(str(e))
        result["status"] = False
        result["data"] = str(e)

    return result
Exemplo n.º 28
0
def set_room_mute(location, room, desired_mute=True, instance_id=0):
    """Sets the mute status of a rendering service in a room.

    Applies to Virtual Media Player.

    Parameters:
    location -- URL to the device description XML of the rendering device.
    room -- The unique device number of the room (UUID). The device must be
    member of the room.
    desired_mute --- Bolean value of True activaes the mute status and a
    value of False deactivates the mute status.
    instance_id --
    """
    if desired_mute == True:
        desired_mute = "1"
    else:
        desired_mute = "0"

    device = upnpclient.Device(location)
    device.RenderingControl.SetRoomMute(InstanceID=instance_id,
                                        Room=room,
                                        DesiredMute=desired_mute)
Exemplo n.º 29
0
def upnp():
    server = request.args.get('server')
    if server == "" or server == "undefined":
        return jsonify({'result': 'no server given'})
    try:
        d = upnpclient.Device(server)
        if request.args.get('action', 'Player.Stop') == 'Player.Open':
            d.AVTransport.SetAVTransportURI(InstanceID='0',
                                            CurrentURI=request.args.get(
                                                'stream',
                                                'http://localhost:18080'),
                                            CurrentURIMetaData='Audioloader')
            d.AVTransport.Play(InstanceID='0', Speed='1')
        else:
            d.AVTransport.Stop(InstanceID='0')

    except Exception as e:
        app.logger.warn('couldnot run upnp commands')
        app.logger.debug(traceback.format_exc())
        return jsonify({'result': 'load failed'})

    return jsonify({'result': 'loaded'})
Exemplo n.º 30
0
    def update(self):
        """Get the latest player details from the device."""

        if self._slave_mode:
            return True

        if self._upnp_device is None:
            for entry in self.upnp_discover(UPNP_TIMEOUT):
                if entry.friendly_name == \
                        self._devicename:
                    self._upnp_device = upnpclient.Device(entry.location)
                    break

        self._lpapi.call('GET', 'getPlayerStatus')
        player_api_result = self._lpapi.data

        if player_api_result is None:
            _LOGGER.warning('Unable to connect to device')
            self._media_title = 'Unable to connect to device'
            return True

        try:
            player_status = json.loads(player_api_result)
        except ValueError:
            _LOGGER.warning("REST result could not be parsed as JSON")
            _LOGGER.debug("Erroneous JSON: %s", player_api_result)
            player_status = None

        if isinstance(player_status, dict):
            self._lpapi.call('GET', 'getStatus')
            device_api_result = self._lpapi.data
            if device_api_result is None:
                _LOGGER.warning('Unable to connect to device')
                self._media_title = 'Unable to connect to device'
                return True

            try:
                device_status = json.loads(device_api_result)
            except ValueError:
                _LOGGER.warning("REST result could not be parsed as JSON")
                _LOGGER.debug("Erroneous JSON: %s", device_api_result)
                device_status = None

            if isinstance(device_status, dict):
                self._wifi_channel = device_status['WifiChannel']
                self._ssid = \
                    binascii.hexlify(device_status['ssid'].encode('utf-8'))
                self._ssid = self._ssid.decode()

            # Update variables that changes during playback of a track.
            self._volume = player_status['vol']
            self._muted = player_status['mute']
            self._seek_position = int(int(player_status['curpos']) / 1000)
            self._position_updated_at = utcnow()
            try:
                self._media_uri = str(bytearray.fromhex(
                    player_status['iuri']).decode())
            except KeyError:
                self._media_uri = None
            self._state = {
                'stop': STATE_PAUSED,
                'play': STATE_PLAYING,
                'pause': STATE_PAUSED,
            }.get(player_status['status'], STATE_UNKNOWN)
            self._source = SOURCES_MAP.get(player_status['mode'],
                                           'WiFi')
            self._sound_mode = SOUND_MODES.get(player_status['eq'])
            self._shuffle = (player_status['loop'] == '2')
            self._playing_spotify = bool(player_status['mode'] == '31')

            self._new_song = self._is_playing_new_track(player_status)
            if self._playing_spotify or player_status['totlen'] == '0':
                self._update_via_upnp()

            elif self._media_uri is not None and self._new_song:
                self._update_from_id3()
                if self._lfmapi is not None and \
                        self._media_title is not None:
                    self._get_lastfm_coverart()
                else:
                    self._media_image_url = None

            self._duration = int(int(player_status['totlen']) / 1000)

        else:
            _LOGGER.warning("JSON result was not a dictionary")

        # Get multiroom slave information
        self._lpapi.call('GET', 'multiroom:getSlaveList')
        slave_list = self._lpapi.data

        try:
            slave_list = json.loads(slave_list)
        except ValueError:
            _LOGGER.warning("REST result could not be parsed as JSON")
            _LOGGER.debug("Erroneous JSON: %s", slave_list)
            slave_list = None

        self._slave_list = []
        if isinstance(slave_list, dict):
            if int(slave_list['slaves']) > 0:
                for slave in slave_list['slave_list']:
                    device = self.hass.data[DATA_LINKPLAY].get(slave['name'])
                    if device:
                        self._slave_list.append(device)
                        device.set_master(self)
                        device.set_slave_mode(True)
                        device.set_media_title("Slave mode")
                        device.set_media_artist(self.name)
                        device.set_volume(slave['volume'])
                        device.set_muted(slave['mute'])
                        device.set_state(self.state)
                        device.set_slave_ip(slave['ip'])
                        device.set_seek_position(self.media_position)
                        device.set_duration(self.media_duration)
                        device.set_position_updated_at(
                            self.media_position_updated_at)
                        device.set_source(self._source)
                        device.set_sound_mode(self._sound_mode)
        else:
            _LOGGER.warning("JSON result was not a dictionary")

        return True